[SPRD] 版本修改集锦

[SPRD] 版本修改集锦1 预装 app 一般就三种情况 预装不可卸载 预装可卸载恢复出厂恢复 预装可卸载恢复出厂不能恢复可参考内置 apk1 1 预装不可卸载这种情况 app 最终位于 system app 或 system pri

大家好,欢迎来到IT知识分享网。

1、预装 app

一般就三种情况,预装不可卸载,预装可卸载恢复出厂恢复,预装可卸载恢复出厂不能恢复

可参考 内置apk

1.1、预装不可卸载

这种情况 app 最终位于 system/app 或 system/priv-app 即可,作为系统应用,不可卸载

Android.mk 中不配置输出路径则默认打包到 system/app

要想打包到 system/priv-app 则配置 LOCAL_PRIVILEGED_MODULE := true

1.2、预装可卸载恢复出厂恢复

这种情况就比较特殊了,不同的厂商会有自己的方法。

MTK 将 app 依旧作为系统 app,增加了一个包名清单可配置要卸载的系统应用,

这样就确保了能卸载,恢复出厂系统应用又能自动恢复。

RK 也是将 app 作为系统 app,通过放置到特殊文件夹确保可卸载,卸载时会将包名写入缓存文件,

恢复出厂系统会读取缓存文件判断是否需要安装对应 app。

SQRD 也有自己的方法,将 app 打包到 system/vital-app 或 system/preloadapp 即可

这两个目录区别如下

preloadapp 目录中的应用在开机的过程是异步安装的(有利于加快开机速度),存在开机后在 home 界面,

该目录下的应用一个个显示出来的现象。如果是开机急于使用的应用,

例如说在 Launcher 上配置了文件夹存放第三方应用,建议放在 vital-app 目录中,如果不要求开机即使用,建议存放在 preloadapp 目录。

vital-app 目录中的应用在开机的过程中是同步安装的,开机后不会出现上述 preloadapp 下应用一个个出现的现象,

但是会造成开机时间相应变长。一般需要开机进入待机就要安装好的应用(如输入法应用)才建议预置到该目录。

Android.mk 中增加配置

LOCAL_MODULE_PATH := $(TARGET_OUT)/preloadapp

LOCAL_MODULE_PATH := $(TARGET_OUT)/vital-app

1.3、预装可卸载恢复出厂不能恢复

这种情况一般都是将 app 打包到 data/app 目录即可

Android.mk 中增加配置

LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)

10.0 存在 bug data/app 中放置了 apk,烧写后系统不能正常启动,会自动进入 recovery 界面,提示需要清除 usedata 数据

也就是 data/app 下的 apk。解决办法 androidQ(10.0) 预装集成apk到data分区

2、系统主题风格切换

apk 中有很多资源文件,包括应用图标和名称。国产手机在系统主题切换这块做的很顶,网上思路很多,这里用一种偷懒的办法单机版本。

aosp 本身 app 图标和名称是非常丑的,这就需要我们给它美化一番。

2.1、获取这些 app 包名

按个点击进入这些 app,依次执行 adb shell dumpsys window | findstr mCurrentFocus 获取包名

2.2、自己搜罗一套精美 icon

2.3、开始替换之旅

替换图标

将 icon 资源文件 copy 至 frameworks/base/core/res/res/drawable-xhdpi/

配置 icon 为 drawable 资源

frameworks/base/core/res/res/values/symbols.xml

+ <!-- // cczheng add for Chromium icon S --> + <java-symbol type="drawable" name="ic_app_deskclock" /> + <java-symbol type="drawable" name="ic_app_settings" /> + <java-symbol type="drawable" name="ic_app_calendar" /> + <java-symbol type="drawable" name="ic_app_email" /> + <java-symbol type="drawable" name="ic_app_music" /> + <java-symbol type="drawable" name="ic_app_camera" /> + <java-symbol type="drawable" name="ic_app_fmradio" /> + <java-symbol type="drawable" name="ic_app_calculator2" /> + <java-symbol type="drawable" name="ic_app_download" /> + <java-symbol type="drawable" name="ic_app_sounder" /> + <java-symbol type="drawable" name="ic_app_gallery" /> + <java-symbol type="drawable" name="ic_app_filemanager" /> + <java-symbol type="drawable" name="ic_app_mms" /> + <java-symbol type="drawable" name="ic_app_browser" /> + <java-symbol type="drawable" name="ic_app_dialer" /> + <java-symbol type="drawable" name="ic_app_contacts" /> + <java-symbol type="drawable" name="ic_app_stk" /> + <java-symbol type="drawable" name="ic_app_quicksearchbox" /> + <java-symbol type="drawable" name="ic_app_map" /> + <java-symbol type="drawable" name="ic_app_store" /> + <java-symbol type="drawable" name="ic_app_vedio" /> + <java-symbol type="drawable" name="ic_app_email" /> + <!-- end --> <java-symbol type="drawable" name="default_wallpaper" /> 

根据包名替换对应 drawable 资源

frameworks/base/core/java/android/app/ApplicationPackageManager.java

@@ -114,6 +114,11 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.HashMap; +import java.util.HashSet; +import android.graphics.BitmapFactory; +import com.android.internal.R; + / @hide */ public class ApplicationPackageManager extends PackageManager { 
    private static final String TAG = "ApplicationPackageManager"; @@ -123,6 +128,10 @@ public class ApplicationPackageManager extends PackageManager { 
    // Default flags to use with PackageManager when no flags are given. private final static int sDefaultFlags = PackageManager.GET_SHARED_LIBRARY_FILES; + // cczheng add for Chromium icon S + private static HashMap<String,Integer> appMaps = new HashMap<>(); + private static String[] appName={ 
   "com.android.deskclock","com.android.settings", + "com.android.calendar","com.android.email", + "com.android.music","com.mediatek.camera", + "com.android.fmradio","com.android.calculator2", + "com.android.documentsui", "com.android.soundrecorder", + "com.android.gallery3d","com.mediatek.filemanager", + "com.android.browser","com.android.mms", + "com.android.dialer","com.android.contacts", + "com.android.stk","com.android.quicksearchbox","com.google.android.apps.maps", + "com.android.vending","com.google.android.videos","com.google.android.calendar", + "com.google.android.gm","com.google.android.music","com.google.android.apps.photos", + "com.google.android.googlequicksearchbox"}; + + private static int[] appImg={ 
   R.drawable.ic_app_deskclock,R.drawable.ic_app_settings, + R.drawable.ic_app_calendar,R.drawable.ic_app_email, + R.drawable.ic_app_music,R.drawable.ic_app_camera, + R.drawable.ic_app_fmradio,R.drawable.ic_app_calculator2, + R.drawable.ic_app_download, R.drawable.ic_app_sounder, + R.drawable.ic_app_gallery,R.drawable.ic_app_filemanager, + R.drawable.ic_app_browser, R.drawable.ic_app_mms, + R.drawable.ic_app_dialer, R.drawable.ic_app_contacts, + R.drawable.ic_app_stk,R.drawable.ic_app_quicksearchbox,R.drawable.ic_app_map, + R.drawable.ic_app_store,R.drawable.ic_app_vedio,R.drawable.ic_app_calendar, + R.drawable.ic_app_email,R.drawable.ic_app_music,R.drawable.ic_app_gallery, + R.drawable.ic_app_quicksearchbox};//E private final Object mLock = new Object(); @@ -1656,6 +1665,10 @@ public class ApplicationPackageManager extends PackageManager { 
    IPackageManager pm) { 
    mContext = context; mPM = pm; +  cczheng add for Chromium icon S + for(int i=0;i<appName.length;i++){ 
    + appMaps.put(appName[i],new Integer(appImg[i])); + }//E } @Override @@ -2832,6 +2848,10 @@ public class ApplicationPackageManager extends PackageManager { 
    if (dr == null) { 
    dr = itemInfo.loadDefaultIcon(this); } + // cczheng add for Chromium icon S + if(appMaps.containsKey(itemInfo.packageName)){ 
    + dr =mContext.getResources().getDrawable(appMaps.get(itemInfo.packageName).intValue()); + }//E return dr; } 

frameworks/base/core/java/android/content/pm/LauncherActivityInfo.java

 +import java.util.HashMap; +import java.util.HashSet; +import android.os.SystemProperties; +import android.graphics.BitmapFactory; +import com.android.internal.R; + @@ -40,6 +46,10 @@ public class LauncherActivityInfo { 
    private ActivityInfo mActivityInfo; private ComponentName mComponentName; private UserHandle mUser; + // cczheng add for Chromium icon S + private static HashMap<String,Integer> appMaps = new HashMap<>(); + private static String[] appName={ 
   "com.android.deskclock","com.android.settings", + "com.android.calendar","com.android.email", + "com.android.music","com.mediatek.camera", + "com.android.fmradio","com.android.calculator2", + "com.android.documentsui", "com.android.soundrecorder", + "com.android.gallery3d","com.mediatek.filemanager", + "com.android.browser","com.android.mms", + "com.android.dialer","com.android.contacts", + "com.android.stk","com.android.quicksearchbox","com.google.android.apps.maps", + "com.android.vending","com.google.android.videos","com.google.android.calendar", + "com.google.android.gm","com.google.android.music","com.google.android.apps.photos", + "com.google.android.googlequicksearchbox"}; + + private static int[] appImg={ 
   R.drawable.ic_app_deskclock,R.drawable.ic_app_settings, + R.drawable.ic_app_calendar,R.drawable.ic_app_email, + R.drawable.ic_app_music,R.drawable.ic_app_camera, + R.drawable.ic_app_fmradio,R.drawable.ic_app_calculator2, + R.drawable.ic_app_download, R.drawable.ic_app_sounder, + R.drawable.ic_app_gallery,R.drawable.ic_app_filemanager, + R.drawable.ic_app_browser, R.drawable.ic_app_mms, + R.drawable.ic_app_dialer, R.drawable.ic_app_contacts, + R.drawable.ic_app_stk,R.drawable.ic_app_quicksearchbox,R.drawable.ic_app_map, + R.drawable.ic_app_store,R.drawable.ic_app_vedio,R.drawable.ic_app_calendar, + R.drawable.ic_app_email,R.drawable.ic_app_music,R.drawable.ic_app_gallery, + R.drawable.ic_app_quicksearchbox};//E @@ -57,6 +67,10 @@ public class LauncherActivityInfo { 
    LauncherActivityInfo(Context context) { 
    mPm = context.getPackageManager(); +  cczheng add for Chromium icon S + for(int i=0;i<appName.length;i++){ 
    + appMaps.put(appName[i],new Integer(appImg[i])); + }//E } @@ -118,6 +132,13 @@ public class LauncherActivityInfo { 
    if (icon == null) { 
    icon = mActivityInfo.loadIcon(mPm); } +  cczheng add for Chromium icon S + if(appMaps.containsKey(mActivityInfo.packageName)){ 
    + try { 
    + icon = mPm.getResourcesForApplication(mActivityInfo.applicationInfo).getDrawable(appMaps.get(mActivityInfo.packageName).intValue()); + } catch (NameNotFoundException | Resources.NotFoundException exc) { 
    + } + }//E return icon; } 

去除图标默认增加的白边

Android 8~Android 11 去掉 Launcher3 默认给 icon 增加的白边

替换名称

launcher3 桌面名称

packages/apps/Launcher3/src/com/android/launcher3/BubbleTextView.java

@@ -291,7 +291,14 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, mDotParams.color = IconPalette.getMutedColor(info.iconColor, 0.54f); setIcon(iconDrawable); - setText(info.title); + // cczheng add for Chromium name S + if ("Chromium".equals(info.title)) { 
    + String appName = getContext().getResources().getString(com.android.internal.R.string.browserName); + setText(appName); + android.util.Log.d("Launcher3","appName="+appName); + }else { 
   //E + setText(info.title); + } if (info.contentDescription != null) { 
    setContentDescription(info.isDisabled() ? getContext().getString(R.string.disabled_app_label, info.contentDescription) 

Settings 应用详情名称

frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java

@@ -1590,6 +1590,10 @@ public class ApplicationsState { 
    this.mounted = true; CharSequence label = info.loadLabel(context.getPackageManager()); this.label = label != null ? label.toString() : info.packageName; + // cczheng add for Chromium name S + if ("org.chromium.chrome".equals(info.packageName)) { 
    + this.label = context.getResources().getString(com.android.internal.R.string.browserName); + }//E } } } 

3、开关机动画、铃声

开机动画资源 bootanimation.zip

关机机动画资源 shutdownanimation.zip

开机铃声资源 bootsound.mp3

注:名称不能改动,将上面三个资源预置到 system/media 目录下

关机动画不能正常播放 bug

frameworks/base/cmds/bootanimation/BootAnimation.cpp

@@ -1088,6 +1088,14 @@ bool BootAnimation::playAnimation(const Animation& animation) continue; //to next part } + +#ifdef BOOTANIMATION_EXT + if (mShuttingDown && mfd == -1 && mWaitForComplete && (i==(pcount-1))) { 
    + ALOGD("shutdown animation finished, quit"); + property_set("service.bootanim.end", "1"); + } +#endif + for (int r=0 ; !part.count || r<part.count ; r++) { 
    // Exit any non playuntil complete parts immediately if(exitPending() && !part.playUntilComplete) @@ -1172,12 +1180,12 @@ bool BootAnimation::playAnimation(const Animation& animation) if(exitPending() && !part.count && mCurrentInset >= mTargetInset) break; } -#ifdef BOOTANIMATION_EXT - if (mShuttingDown && mfd == -1 && mWaitForComplete) { 
    - ALOGD("shutdown animation part1 finished, quit"); - property_set("service.bootanim.end", "1"); - } -#endif 

frameworks/base/services/core/java/com/android/server/power/ShutdownAnimation.java

@@ -38,6 +38,7 @@ public class ShutdownAnimation { 
    try { 
    mPlayAnim = true; Slog.i(TAG, "exec the bootanimation "); + SystemProperties.set("service.wait_for_bootanim", "1"); SystemProperties.set("service.bootanim.exit", "0"); SystemProperties.set("service.bootanim.end", "0"); SystemProperties.set("service.bootanim.shutdown", "1"); 

4、双卡改单卡配置

请在 device/sprd/sharkl3/s9863a1h10/s9863a1h10_Natv.mk (项目对应的具体工程文件)最下面添加如下代码。

5、OTA 相关

通用打包指令,通用校验方法,通用升级方法

RecoverySystem.verifyPackage() 对 ota 升级包进行校验,报错 log 如下

libvintf: Could not open /proc/config.gz: 13 2021-03-26 11:27:14.981 2495-2758/com.wxtx.systemupdate W/libvintf: Cannot fetch or parse /proc/config.gz: Permission denied 2021-03-26 11:27:14.981 2495-2758/com.wxtx.systemupdate W/libvintf: Cannot fetch or parse kernel sepolicy version: Operation not permitted 2021-03-26 11:27:14.992 2495-2758/com.wxtx.systemupdate W/VintfObject: VintfObject.verify() returns 1: Runtime info and framework compatibility matrix are incompatible: kernelSepolicyVersion = 0 but required >= 30 2021-03-26 11:27:15.002 2495-2758/com.wxtx.systemupdate W/System.err: java.security.SignatureException: package compatibility verification failed 2021-03-26 11:27:15.003 2495-2758/com.wxtx.systemupdate W/System.err: at android.os.RecoverySystem.verifyPackage(RecoverySystem.java:350) 2021-03-26 11:27:15.003 2495-2758/com.wxtx.systemupdate W/System.err: at com.wxtx.systemdownload.helper.SystemUpgrade$2.onConfirmUpdate(SystemUpgrade.java:141) 2021-03-26 11:27:15.003 2495-2758/com.wxtx.systemupdate W/System.err: at com.wxtx.systemdownload.helper.SystemUpgrade$2.run(SystemUpgrade.java:129) 

解决办法如下

system/sepolicy/private/system_app.te
system/sepolicy/prebuilts/api/29.0/private/system_app.te

allow system_app config_gz:file { 
    read open }; allow system_app selinuxfs:file { 
    read open }; 

device/sprd/sharkle/common/sepolicy/uncrypt.te

allow uncrypt mmcblk_device:blk_file { 
    open write }; allow uncrypt userdata_block_device:blk_file { 
    open write }; allow uncrypt system_app_data_file:dir { 
   read}; allow uncrypt system_app_data_file:file { 
   read}; # For GOTA allow uncrypt self:capability { 
    fowner sys_admin }; allow uncrypt ota_package_file:file { 
    write }; # For inner local ota update in /data/meida/0 allow uncrypt media_rw_data_file:file { 
    open getattr read ioctl write }; allow uncrypt media_rw_data_file:dir { 
    open getattr read search }; allow uncrypt metadata_file:dir { 
    search }; 

https://blog.csdn.net/u0/article/details//

https://blog.csdn.net/m/article/details/

6、解锁 OEM 方法

展讯设备解锁需要在 linux 环境下执行相关指令

1、虚拟机-可移动设备-选中手机从主机切换为虚拟机

sudo vim /etc/udev/rules.d/51-android.rules 没有这个文件就自己新建一个

SUBSYSTEM==“usb”,ATTRS{idVendor}“vid”,ATTRS{idProduct}“pid”,MODE=“0666”

sudo chmod a+rx /etc/udev/rules.d/51-vboxadd.rules

3、重新插拔设备,齐活

环境搞定了,接下来整理需要的几个关键文件

将下面三个文件 copy 到新建文件夹中

vendor\sprd\proprietories-source\packimage_scripts\signidentifier_unlockbootloader.sh
vendor\sprd\proprietories-source\packimage_scripts\signimage\sprd\config\rsa4096_vbmeta.pem

4、开始解锁

4.3、使用证书 certificate.bin 解锁

c、按设备音量-键确认

7、状态栏左上角显示运营商信息

frameworks\base\packages\SystemUI\res\values\config.xml

<!-- Whether to show operator name in the status bar --> <bool name="config_showOperatorNameInStatusBar">true</bool> 

以前都是自己加一个在状态栏右边的,现在发现源码中其实已经自带了,打开这个配置就行

CollapsedStatusBarFragment.java –> initOperatorName() OperatorNameView.java

8、状态栏右边增加 SIM 未插入图标

frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\PhoneStatusBarPolicy.java

 import android.database.ContentObserver; - +import android.telephony.TelephonyManager; bar at boot @@ -263,6 +263,8 @@ public class PhoneStatusBarPolicy }); + updateNoSim(); + } @Override @@ -405,6 +407,19 @@ public class PhoneStatusBarPolicy mIconController.setIconVisibility(mSlotSpeakerphone, visible); }/ + private final void updateNoSim() { 
    + int iconId = R.drawable.ic_qs_no_sim; + String contentDescription = + mContext.getString(R.string.accessibility_quick_settings_bluetooth_on); + TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + int simState = telMgr.getSimState(); + if (simState == TelephonyManager.SIM_STATE_ABSENT) { 
    + android.util.Log.d("PhoneStatusBarPolicy", "simState="+simState); + mIconController.setIcon("nosim", iconId, contentDescription); + mIconController.setIconVisibility("nosim", true); + } + } private final void updateBluetooth() { 
    int iconId = R.drawable.stat_sys_data_bluetooth_connected; 

9、Launcher3 去除 HotSeat 栏

packages\apps\Launcher3\src\com\android\launcher3\DeviceProfile.java

 hotseatBarSizePx = ResourceUtils.pxFromDp(inv.iconSize, dm) + (isVerticalBarLayout() ? (hotseatBarSidePaddingStartPx + hotseatBarSidePaddingEndPx) : (res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_extra_vertical_size) + hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx)); android.util.Log.d("DeviceProfile","1 hotseatBarSizePx="+hotseatBarSizePx); + hotseatBarSizePx = 0;//set 0 hide hotseat  // Calculate all of the remaining variables. updateAvailableDimensions(dm, res); // Hotseat if (isVerticalLayout) { 
    hotseatBarSizePx = iconSizePx + hotseatBarSidePaddingStartPx + hotseatBarSidePaddingEndPx; android.util.Log.d("DeviceProfile","3 hotseatBarSizePx="+hotseatBarSizePx); + hotseatBarSizePx = 0;//set 0 hide hotseat  } hotseatCellHeightPx = iconSizePx; // We want the edges of the hotseat to line up with the edges of the workspace, but the // icons in the hotseat are a different size, and so don't line up perfectly. To account // for this, we pad the left and right of the hotseat with half of the difference of a // workspace cell vs a hotseat cell. float workspaceCellWidth = (float) widthPx / inv.numColumns; + float hotseatCellWidth = 0;//(float) widthPx / inv.numHotseatIcons; int hotseatAdjustment = Math.round((workspaceCellWidth - hotseatCellWidth) / 2); mHotseatPadding.set( hotseatAdjustment + workspacePadding.left + cellLayoutPaddingLeftRightPx, hotseatBarTopPaddingPx, hotseatAdjustment + workspacePadding.right + cellLayoutPaddingLeftRightPx, hotseatBarBottomPaddingPx + mInsets.bottom + cellLayoutBottomPaddingPx); 

10、移动数据流量开关增加密码对话框

frameworks/base/packages/SystemUI/res/values-zh-rCN/strings.xml frameworks/base/packages/SystemUI/res/values/strings.xml frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerUI.java frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java packages/apps/Settings/src/com/android/settings/accounts/TopLevelAccountEntryPreferenceController.java packages/apps/Settings/src/com/android/settings/network/telephony/MobileDataPreferenceController.java + <string name="title_data">"输入密码"</string> + <string name="title_data_ok">"开启"</string> + <string name="title_data_cancel">"取消"</string> + <string name="title_passerror">"错误! 再试一次"</string> + <string name="title_data">Input password</string> + <string name="title_data_ok">ON</string> + <string name="title_data_cancel">CANCEL</string> + <string name="title_passerror">Error! Try again</string> 

frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java

@@ -443,6 +443,43 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { 
    mNoMan.notifyAsUser( TAG_TEMPERATURE, SystemMessage.NOTE_THERMAL_SHUTDOWN, n, UserHandle.ALL); } + // add start  + @Override + public void showOpenMobileDataAlarm() { 
    + mHandler.post(() -> showOpenMobileDataAlarmInternal()); + } + + private void showOpenMobileDataAlarmInternal() { 
    + final android.widget.EditText editText = new android.widget.EditText(mContext); + editText.setInputType(0x00000012); + final SystemUIDialog d = new SystemUIDialog(mContext, R.style.Theme_SystemUI_Dialog_Alert); + d.setCancelable(true); + d.setTitle(R.string.title_data); + d.setView(editText); + d.setShowForAllUsers(true); + d.setPositiveButton((R.string.title_data_ok), + (dialogInterface, which) -> { 
    + String password = editText.getText().toString(); + String password2 = android.os.SystemProperties.get("persist.pdd.data.password", ""); + if (TextUtils.isEmpty(password) || !password2.equals(password)) { 
    + android.widget.Toast.makeText(mContext, R.string.title_passerror, + android.widget.Toast.LENGTH_LONG).show(); + }else{ 
    + //adb shell settings get global mobile_data + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.MOBILE_DATA, 1); + } + }); + d.setNegativeButton((R.string.title_data_cancel), + (dialogInterface, which) -> { 
    + }); + d.setOnDismissListener(dialogInterface -> { 
    + Settings.Global.putInt(mContext.getContentResolver(), "pdd_mobile_data", 0); + }); + d.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + d.show(); + } + // add end  @Override public void showUsbHighTemperatureAlarm() { 
    

frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerUI.java

@@ -55,6 +55,10 @@ import java.util.Arrays; import java.util.concurrent.Future; import com.sprd.systemui.power.SprdPowerUI; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.widget.EditText; + public class PowerUI extends SystemUI { 
    static final String TAG = "PowerUI"; @@ -153,6 +157,20 @@ public class PowerUI extends SystemUI { 
    doUsbThermalEventListenerRegistration(); } }); + // add + resolver.registerContentObserver( + Settings.Global.getUriFor("pdd_mobile_data"), + false /*notifyForDescendants*/, + new ContentObserver(mHandler) { 
    + @Override + public void onChange(boolean selfChange) { 
    + int state = Settings.Global.getInt(mContext.getContentResolver(), + "pdd_mobile_data", 0); + if (state == 1) { 
    + mWarnings.showOpenMobileDataAlarm(); + } + } + });//end initThermalEventListeners(); } @@ -220,6 +238,7 @@ public class PowerUI extends SystemUI { 
    filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_USER_SWITCHED); + filter.addAction("cn.pdd.action.opendata"); mContext.registerReceiver(this, filter, null, mHandler); } @@ -313,6 +332,8 @@ public class PowerUI extends SystemUI { 
    mScreenOffTime = -1; } else if (Intent.ACTION_USER_SWITCHED.equals(action)) { 
    mWarnings.userSwitched(); + }else if ("cn.pdd.action.opendata".equals(action)) { 
    + //mWarnings.showOpenMobileDataAlarm(); } else { 
    Slog.w(TAG, "unknown intent: " + intent); } @@ -654,6 +675,9 @@ public class PowerUI extends SystemUI { 
    void showHighTemperatureWarning(); + // + void showOpenMobileDataAlarm(); + / * Display USB port overheat alarm */ 

frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java

 protected void handleClick() { 
    /* UNISOC: bug @{ */ Log.d(TAG, "handleClick mHasEvent : " + mHasEvent); + + // add start  + int state = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.MOBILE_DATA, 1); + if (state == 0) { 
    + Settings.Global.putInt(mContext.getContentResolver(), "pdd_mobile_data", 1); + return; + }//end + if (mHasEvent) { 
    return; } 

packages/apps/Settings/src/com/android/settings/network/telephony/MobileDataPreferenceController.java

 import com.android.settingslib.core.lifecycle.events.OnStop; import java.util.List; + +import android.provider.Settings; +import android.provider.Settings.Global; / * Preference controller for "Mobile data" */ @@ -99,6 +102,7 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon @Override public boolean handlePreferenceTreeClick(Preference preference) { 
    + android.util.Log.d("MobileDataController","handlePreferenceTreeClick"); if (TextUtils.equals(preference.getKey(), getPreferenceKey())) { 
    if (mNeedDialog) { 
    showDialog(mDialogType); @@ -111,8 +115,13 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon @Override public boolean setChecked(boolean isChecked) { 
    + // add start + if (isChecked) { 
    + Settings.Global.putInt(mContext.getContentResolver(), "pdd_mobile_data", 1); + return false; + }//end mNeedDialog = isDialogNeeded(); - + android.util.Log.d("MobileDataController","setChecked="+isChecked+" mNeedDialog="+mNeedDialog); if (!mNeedDialog) { 
    // Update data directly if we don't need dialog MobileNetworkUtils.setMobileDataEnabled(mContext, mSubId, isChecked, false); 

11、返回键删除正在编辑的 EditText 内容

frameworks\base\core\java\android\app\Activity.java

import android.widget.EditText; public boolean onKeyUp(int keyCode, KeyEvent event) { 
    if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.ECLAIR) { 
    if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking() && !event.isCanceled()) { 
    /* onBackPressed(); return true;*/ //cczheng add start  if (isResumed()) { 
    View decorView = this.getWindow().getDecorView(); if (decorView != null) { 
    View focus = decorView.findFocus(); if (focus!=null && focus instanceof EditText) { 
    EditText editText = (EditText)focus; CharSequence text = editText.getText(); if (text!=null && text.length()>0) { 
    int delKeyCode = KeyEvent.KEYCODE_DEL; editText.onKeyDown(delKeyCode, new KeyEvent(KeyEvent.ACTION_DOWN, delKeyCode)); return true; } } } onBackPressed(); //MTK modify END return true; } else { 
    return false; }//cczheng add end } } return false; } 

11、去除 Launcher 图标右上角未读消息小圆点提示

Settings.Secure.putInt(getContentResolver(), Settings.Secure.NOTIFICATION_BADGING, 0);

12、WIFI 已连接,但无法访问互联网

buUsbV.png

展讯自己把 CAPTIVE_PORTAL_MODE 默认值修改为0了,所以当你真正连接到没有物联网的wifi时,不会提示无法访问互联网。

注释这个 CAPTIVE_PORTAL_MODE 默认赋值就行

adb shell settings get global captive_portal_mode

  • 0:彻底禁用检测
  • 1:检测到需要登录则弹窗提醒
  • 2:检测到需要登录则自动断开此热点并不再自动连接

frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java

  //loadIntegerSetting(stmt, Settings.Global.CAPTIVE_PORTAL_MODE,
             // R.integer.captive_portal_mode);

这个放开后,wifi 连接后会有校验,真正能上网的wifi也会提示无法访问互联网

将下面校验网址改成国内可以访问到的即可

packages/modules/NetworkStack/res/values/config.xml

    <!-- HTTP URL for network validation, to use for detecting captive portals. -->
    <string name="default_captive_portal_http_url" translatable="false">http://www.googleapis.cn/generate_204</string>

    <!-- HTTPS URL for network validation, to use for confirming internet connectivity. -->
    <string name="default_captive_portal_https_url" translatable="false">http://www.googleapis.cn/generate_204</string>

去除展讯自己加的wifi连接成功后网络主界面多增当前连接Preference

packages/apps/Settings/src/com/android/settings/network/MultiNetworkHeaderController.java

 @Override
    public int getAvailabilityStatus() { 
    
 return CONDITIONALLY_UNAVAILABLE;
 }

https://blog.csdn.net/weixin_44008788/article/details/115797278

13、WLAN 直连默认名称、WLAN 热点名称、蓝牙默认名称

frameworks\opt\net\wifi\service\java\com\android\server\wifi\p2p\WifiP2pServiceImpl.java

  private String getPersistedDeviceName() { 
    
            String deviceName = mFrameworkFacade.getStringSetting(mContext,
                    Settings.Global.WIFI_P2P_DEVICE_NAME);
            if (deviceName == null) { 
    
                // We use the 4 digits of the ANDROID_ID to have a friendly
                // default that has low likelihood of collision with a peer
                String id = mFrameworkFacade.getSecureStringSetting(mContext,
                        Settings.Secure.ANDROID_ID);
                String ssid = WifiFeaturesUtils.FeatureProperty.SUPPORT_SPRD_P2P_CUSTOMIZED_NAME;
                /*if (ssid != null && ssid.isEmpty()) { return "Android_" + id.substring(0, 4); } else { return ssid; }*/
                //cczheng change default wifip2p name
                return android.os.SystemProperties.get("ro.product.model");
            }
            return deviceName;
        }

frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiApConfigStore.java

    private WifiConfiguration getDefaultApConfiguration() { 
    
        WifiConfiguration config = new WifiConfiguration();
        config.apBand = WifiConfiguration.AP_BAND_2GHZ;
        String ssid = WifiFeaturesUtils.FeatureProperty.SUPPORT_SPRD_SOFTAP_CUSTOMIZED_NAME;
        if (ssid != null && ssid.isEmpty()) { 
    
            config.SSID = mContext.getResources().getString(
                R.string.wifi_tether_configure_ssid_default) + "_" + getRandomIntForDefaultSsid();
        } else { 
    
            config.SSID = ssid;
        }
        //cczheng change default wifiAP name add
        config.SSID = android.os.SystemProperties.get("ro.product.model");
		//cczheng end
        config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
        String randomUUID = UUID.randomUUID().toString();
        //first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
        config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9, 13);
        return config;
    }

device/generic/common/bluetooth/bdroid_buildcfg.h

 #define _BDROID_BUILDCFG_H
 
-#define BTM_DEF_LOCAL_NAME   "Android Bluedroid"
+// #define BTM_DEF_LOCAL_NAME "Android Bluedroid"
+#define BTM_DEF_LOCAL_NAME   "HTCOne"
 
 #endif

system/bt/internal_include/bt_target.h

  * product model name is used as the default local name.
 */
#ifndef BTM_DEF_LOCAL_NAME
-#define BTM_DEF_LOCAL_NAME ""
+#define BTM_DEF_LOCAL_NAME "HTCOne"
#endif
  •  strncpy(btif_default_local_name, prop_model, max_len);
    
  •  // strncpy(btif_default_local_name, prop_model, max_len);
    
  •  if (strncmp(prop_model, "IK-WST08", 5) == 0){
    
  •    strncpy(btif_default_local_name, prop_model, max_len);
    
  •  }else{
    
  •    char temp[] = "Android Bluedroid";
    
  •    strncpy(btif_default_local_name, temp, max_len);
    
  • }
    btif_default_local_name[max_len] = ‘\0’;
    }

     }//end
    

14、系统默认打开深色主题背景功能

Settings.Secure.putInt(getContentResolver(), Settings.Secure.DARK_MODE_DIALOG_SEEN, 1);

2、Settings 中开机启动后再次调用 setNightMode

vendor/sprd/platform/packages/apps/Settings/src/com/sprd/settings/timerpower/AlarmInitReceiver.java

 
+import android.app.UiModeManager;
+import android.provider.Settings;
+
 public class AlarmInitReceiver extends BroadcastReceiver { 
    
 
     private Context mContext;
@@ -46,6 +49,12 @@ public class AlarmInitReceiver extends BroadcastReceiver { 
    
         Log.v("AlarmInitReceiver ---- intent = " + intent);
         if(Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { 
    
             isBoot = true;
+            String keyMode =  Settings.System.getString(context.getContentResolver(),"test.pdd.night");
+            if (!"1".equals(keyMode)) { 
    
+                context.getSystemService(UiModeManager.class).setNightMode(UiModeManager.MODE_NIGHT_YES);
+                Log.v("AlarmInitReceiver ---- MODE_NIGHT_YES");
+                Settings.System.putString(context.getContentResolver(), "test.pdd.night", "1");
+            }
         }
         if (null == mHanderThread) { 
    
             Log.v("onReceive mHanderThread is null.");

15、系统默认关闭超级省电模式

超级省电模式 功能由 ro.sys.pwctl.ultrasaving 控制,

1 启用超级省电模式,系统中包含相关菜单

0 关闭超级省电模式

16、Launcher3 空白长按弹出 popwindow 功能跳转定制

packages\apps\Launcher3\src\com\android\launcher3\views\OptionsPopupView.java

options.add(new OptionItem(R.string.contact_button_text, R.drawable.ic_setting,
                ControlType.SETTINGS_BUTTON, OptionsPopupView::startContact));
				

  public static boolean startContact(View view) { 
    
        Launcher launcher = Launcher.getLauncher(view.getContext());
        launcher.startActivity(new Intent()
                .setComponent(new android.content.ComponentName("com.android.contacts",
                    "com.android.contacts.activities.PeopleActivity"))
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
        return true;
    }

17、设备壁纸页面直接跳转

想要直接跳转到系统自带所有壁纸详细页面,WallpaperPicker2 中并没有暴露直接页面 IndividualPickerActivity

packages\apps\WallpaperPicker2\AndroidManifest.xml

  <activity android:name="com.android.wallpaper.picker.individual.IndividualPickerActivity"
        android:label="@string/app_name"
        android:theme="@style/WallpaperTheme"
        android:resizeableActivity="true"
        android:parentActivityName="com.android.wallpaper.picker.TopLevelPickerActivity">
        <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
    </activity>

解决 IndividualPickerActivity 中加载数据 mCategory 为 null 问题,默认的数据加载 Application 中 load 一次后,其它各个

子页面直接使用即可,我们现在直接跳转子页面,很显然数据是拿不到的,所以就得自己规避这个问题。

通过传递参数 mode 来区分是直接跳转还是原有从主页点击进入,direct 模式下先主动 load 一遍数据,等数据

load 成功后再显示界面

packages\apps\WallpaperPicker2\src\com\android\wallpaper\picker\individual\IndividualPickerActivity.java


import android.os.Handler;
import android.os.Message;

import com.android.wallpaper.module.WallpapersInjector;
import com.android.wallpaper.model.CategoryReceiver;

 Bundle savedInstanceState;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) { 
    
        super.onCreate(savedInstanceState);
        this.savedInstanceState = savedInstanceState;
        setContentView(R.layout.activity_single_fragment_with_toolbar);

        if ("direct".equals(getIntent().getStringExtra("mode"))) { 
    
            android.util.Log.i(TAG,"setInjector WallpapersInjector");
            InjectorProvider.setInjector(new WallpapersInjector());
            InjectorProvider.getInjector().getCategoryProvider(this).fetchCategories(new CategoryReceiver() { 
    
                @Override
                public void onCategoryReceived(Category category) { 
    
                    android.util.Log.d(TAG,"onCategoryReceived "+ category.getCollectionId());
                    if ("on_device_wallpapers".equals(category.getCollectionId())) { 
    
                        mHandler.sendEmptyMessage(100);
                    }
                }

                @Override
                public void doneFetchingCategories() { 
    
                    
                }
            }, true);
        }else{ 
    
            doRealyView();
        }
    }

    private Handler mHandler = new Handler() { 
    
        public void handleMessage(Message msg) { 
    
            doRealyView();
        }
    };

    private void doRealyView(){ 
    
         // Set toolbar as the action bar.
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mPreviewIntentFactory = new PreviewActivityIntentFactory();
        Injector injector = InjectorProvider.getInjector();
        mWallpaperPersister = injector.getWallpaperPersister(this);
        mLiveWallpaperStatusChecker = injector.getLiveWallpaperStatusChecker(this);

        FragmentManager fm = getSupportFragmentManager();
        Fragment fragment = fm.findFragmentById(R.id.fragment_container);

        mCategoryCollectionId = (savedInstanceState == null)
                ? getIntent().getStringExtra(EXTRA_CATEGORY_COLLECTION_ID)
                : savedInstanceState.getString(KEY_CATEGORY_COLLECTION_ID);
        android.util.Log.d(TAG,"mCategoryCollectionId="+mCategoryCollectionId);
        mCategory = injector.getCategoryProvider(this).getCategory(mCategoryCollectionId);
        if (mCategory == null) { 
    
            android.util.Log.e(TAG,"getOnDeviceCategory=");
            // mCategory = getOnDeviceCategory(this);
        }

        if (mCategory == null) { 
    
            DiskBasedLogger.e(TAG, "Failed to find the category: " + mCategoryCollectionId, this);
            // We either were called with an invalid collection Id, or we're restarting with no
            // saved state, or with a collection id that doesn't exist anymore.
            // In those cases, we cannot continue, so let's just go back.
            finish();
            return;
        }

        setTitle(mCategory.getTitle());
        getSupportActionBar().setTitle(mCategory.getTitle());
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        toolbar.getNavigationIcon().setTint(getColor(R.color.toolbar_icon_color));
        toolbar.getNavigationIcon().setAutoMirrored(true);

        boolean isInMultiWindowMode = isInMultiWindowMode();
        android.util.Log.e(TAG,"isInMultiWindowMode="+isInMultiWindowMode);
        getWindow().setStatusBarColor(0);//for bug StatusBar show half
        getWindow().getDecorView().setSystemUiVisibility(
                getWindow().getDecorView().getSystemUiVisibility()
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        getWindow().getDecorView().setOnApplyWindowInsetsListener((view, windowInsets) -> { 
    
            view.setPadding(
                    isInMultiWindowMode ? windowInsets.getSystemWindowInsetLeft() : view.getPaddingLeft(),
                    windowInsets.getSystemWindowInsetTop(),
                    isInMultiWindowMode ? windowInsets.getSystemWindowInsetRight() : view.getPaddingRight(),
                    view.getPaddingBottom());
            // Consume only the top inset (status bar), to let other content in the Activity consume
            // the nav bar (ie, by using "fitSystemWindows")
            if (BuildCompat.isAtLeastQ()) { 
    
                WindowInsets.Builder builder = new WindowInsets.Builder(windowInsets);
                android.util.Log.i(TAG,"left="+windowInsets.getSystemWindowInsetLeft()
                    +" right="+windowInsets.getStableInsetRight()
                    +" bottom="+windowInsets.getSystemWindowInsetBottom());
                builder.setSystemWindowInsets(Insets.of(windowInsets.getSystemWindowInsetLeft(),
                        0, windowInsets.getStableInsetRight(),
                        windowInsets.getSystemWindowInsetBottom()));
                return builder.build();
            } else { 
    
                return windowInsets.replaceSystemWindowInsets(
                        windowInsets.getSystemWindowInsetLeft(),
                        0, windowInsets.getStableInsetRight(),
                        windowInsets.getSystemWindowInsetBottom());
            }
        });

        if (fragment == null) { 
    
            fragment = injector.getIndividualPickerFragment(mCategoryCollectionId);
            fm.beginTransaction()
                    .add(R.id.fragment_container, fragment)
                    .commit();
        }
    }

18、横屏紧急拨号界面不居中显示问题

去除这个属性

 <LinearLayout style="@style/DialpadKeyInternalLayoutStyle"
	 android:orientation="horizontal" 
	android:baselineAligned="false">

19、系统蓝牙名称兼容修改

蓝牙名称真正获取值的地方位于 system/bt/btif/src/btif_dm.cc btif_get_default_local_name()

原有逻辑先读取 BTM_DEF_LOCAL_NAME 是否不为空,为空则读取设备 ro.product.model 值

+#define BTM_DEF_LOCAL_NAME   ""
+// #define BTM_DEF_LOCAL_NAME "Android Bluedroid"
 
 #endif

system/bt/internal_include/bt_target.h

 #ifndef BTM_DEF_LOCAL_NAME
+#define BTM_DEF_LOCAL_NAME   ""
+// #define BTM_DEF_LOCAL_NAME "Android Bluedroid"
#endif

然后从prop中读取兼容名称配置

system/bt/btif/src/btif_dm.cc
static char* btif_get_default_local_name() {

if (btif_default_local_name[0] == ‘\0’) {

int max_len = sizeof(btif_default_local_name) – 1;
if (BTM_DEF_LOCAL_NAME[0] != ‘\0’) {

strncpy(btif_default_local_name, BTM_DEF_LOCAL_NAME, max_len);
} else {

char prop_model[PROPERTY_VALUE_MAX];
osi_property_get(PROPERTY_PRODUCT_MODEL, prop_model, “”);







  •  // strncpy(btif_default_local_name, prop_model, max_len);
    
  •  // change this
    
  •  if (strncmp(prop_model, "AVSCK", 5) == 0){
    
  •    strncpy(btif_default_local_name, prop_model, max_len);
    
  •  }else{
    
  •    char temp[] = "HTC ONE";
    
  •    strncpy(btif_default_local_name, temp, max_len);
    
  •  }//end
    

    }
    btif_default_local_name[max_len] = ‘\0’;
    }
    return btif_default_local_name;
    }



# 20、设置锁屏后锁屏界面默认显示向上滑动已解锁frameworks/base/packages/SystemUI/res/layout/keyguard_bottom_area.xml```java                 android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"                 android:accessibilityLiveRegion="polite" />+            <!--  add unlock text always show -->+            <TextView+                android:id="@+id/unlock_text"+                android:layout_width="match_parent"+                android:layout_height="wrap_content"+                android:text="@string/keyguard_unlock"+                android:gravity="center"+                android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"/>              <LinearLayout

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java

     public void onUnlockHintStarted() { 
    
         mFalsingManager.onUnlockHintStarted();
-        mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
+        // mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);//remove click don't auto swap change
     }

21、去除12新加调用相机时右上角小绿点

frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\events\PrivacyDotViewController.kt

    val contentDescription: String? = null
) { 
    
    fun shouldShowDot(): Boolean { 
    
-        return systemPrivacyEventIsActive && !shadeExpanded && !qsExpanded
+		//return systemPrivacyEventIsActive && !shadeExpanded && !qsExpanded
+		return false
    }

22、横屏 Activity 调用键盘静止全屏覆盖

Activity 设置 style

+    <style name="Theme.Settings.ImeNoFull" parent="Theme.Settings">
+        <item name="android:imeOptions">flagNoExtractUi|flagNoFullscreen</item>
+    </style>

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/119646.html

(0)
上一篇 2025-11-04 07:00
下一篇 2025-11-04 07:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信