Android 5.1

Android 5.1 - 7.1 系统(framework)定制、修改、移植、总结 - 上篇

 

目录

1:修改开机logo

2:Framework(SysteimUI) Android在状态栏增加耳机拔插图标

3:Android--隐藏状态栏图标

4:android 5.1 usb调试默认关闭设置方法

5:【Audio】【音量曲线】【响度】如何修改音量曲线?

6:【audio】【底噪】【功放延迟关闭问题】如何解决在关闭喇叭后喇叭还是有几秒底噪问题?

 7:【audio】【usb】【UAC】如何在高通平台关闭usb audio驱动功能?

8:【Modem】【GPS】GPS定位基础术语介绍 

9:android:关掉系统的 安全模式

10:google全家桶套餐下载地址 

11:【Android】在SElinux下 如何获得对一个内核节点的访问权限 

12:如何区分欧标和美标耳机

13: 高通耳机增益简单调试方案

14:高通工具acdb音频配置文件使用方案 

15:屏蔽所有物理按键

 16: vendor下的应用第一次自启

 17:Android framework 修改系统声音最大值默认值以及系统亮度默认值最大值位置 

18:消除原生Android网络状态上的惊叹号

 18:件上是单麦但是代码中默认配置是双麦属性的问题

  19:Android系统修改所有应用能读写SD卡

20:Android 6.0以上 默认允许应用弹窗申请权限 

21:Android 系统增加默认属性 Settings.System.putInt

21:Android 系统USER版本去掉 USB插入调试确认框

22 编译 报错:error while loading shared libraries: libz.so.1: cannot open shared object file

23高通平台关闭usb audio驱动功能?

24 提高Android源代码的编译效率

25Android编译环境常用的配置 

26:android 物联设备 省电开发之cpu降频 

27:Android 插拔充电器增加声音

28:高通SPI屏视频播放RGB红蓝颜色反了,在电脑播放正常

29: android5.1 按下power键 系统不休眠

30: android5.1  电话白名单以及黑名单 逻辑

31: android5.1-7.1- 8.1 电话接通成功并广播


修改开机logo有两种方法,一种直接去改c语言代码,第二种替换图片用python生成splash。第一种方法我没试过,感觉挺麻烦的,还有分辨率限制,超过多少分辨率就不能用第一种方法。

  1. 修改的文件路径LINUX/android/bootable/bootloader/lk/splash
  2. 准备好logo图片(png、bmp格式)
  3. 查看中原图片的分辨率,修改logo图片 保证 分辨率 一致
  4. 生成splash.img镜像文件

注:图片分辨率很重要!很重要!很重要!

生成splash.img 步骤

  1.  
    The steps to generate a splash.img:
  2.  
     
  3.  
    1 sudo apt-get install python-imaging
  4.  
     
  5.  
    2 python ./logo_gen.py boot_001.png (*.bmp)

为了减少编译时间可以直接将生成好的splash.img将刷机包中的文件替换掉。

2:Framework(SysteimUI) Android在状态栏增加耳机拔插图标

Android 4.1在拔插耳机时,状态栏没有提示图标。最近做了这个新的需求,步骤如下:
1、在frameworksasepackagesSystemUI esdrawable-Xdpi下增加一个耳机图片stat_sys_headset.png。drawable-Xdpi中的X根据手机的分辨率来确定,我的手机用的是drawable-hdpi;

2、在frameworksasepackagesSystemUIsrccomandroidsystemuistatusbarphonePhoneStatusBarPolicy.java中增加下面的代码:

  1.  
    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
  2.  
    @Override
  3.  
    public void onReceive(Context context, Intent intent) {
  4.  
    String action = intent.getAction();
  5.  
    if (action.equals(Intent.ACTION_ALARM_CHANGED)) {
  6.  
    updateAlarm(intent);
  7.  
    }
  8.  
    else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) {
  9.  
    updateSyncState(intent);
  10.  
    }
  11.  
    else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) ||
  12.  
    action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
  13.  
    updateBluetooth(intent);
  14.  
    }
  15.  
    /*add code for adding headset icon in statusbar.*/
  16.  
    else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
  17.  
    updateHeadsetState(intent);
  18.  
    }
  19.  
    //end
  20.  
    else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
  21.  
    action.equals(AudioManager.VIBRATE_SETTING_CHANGED_ACTION)) {
  22.  
    updateVolume();
  23.  
    }
  24.  
    else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
  25.  
    updateSimState(intent);
  26.  
    }
  27.  
    else if (action.equals(TtyIntent.TTY_ENABLED_CHANGE_ACTION)) {
  28.  
    updateTTY(intent);
  29.  
    } else if (action.equals(Intent.ACTION_LOCALE_CHANGED)) {
  30.  
     
  31.  
    // when acceptting the locale change event,reload USB connection notification.
  32.  
    boolean isUsbConnected = mStorageManager.isUsbMassStorageConnected();
  33.  
    mStorageNotification.onUsbMassStorageConnectionChanged(isUsbConnected);
  34.  
    }
  35.  
    }
  36.  
    };
  37.  
     
  38.  
    public PhoneStatusBarPolicy(Context context) {
  39.  
    mContext = context;
  40.  
     
  41.  
    // init StorageNotification object
  42.  
    mStorageNotification = new StorageNotification(mContext);
  43.  
    mService = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);
  44.  
     
  45.  
    // listen for broadcasts
  46.  
    IntentFilter filter = new IntentFilter();
  47.  
    filter.addAction(Intent.ACTION_ALARM_CHANGED);
  48.  
    filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
  49.  
    filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
  50.  
    filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
  51.  
    filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
  52.  
    filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
  53.  
    /*add code for adding headset icon in statusbar.*/
  54.  
    filter.addAction(Intent.ACTION_HEADSET_PLUG);
  55.  
    //end
  56.  
    filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
  57.  
    filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
  58.  
     
  59.  
    // add locale change event filter
  60.  
    filter.addAction(Intent.ACTION_LOCALE_CHANGED);
  61.  
    mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
  62.  
     
  63.  
    int numPhones = MSimTelephonyManager.getDefault().getPhoneCount();
  64.  
    mSimState = new IccCard.State[numPhones];
  65.  
    for (int i=0; i < numPhones; i++) {
  66.  
    mSimState[i] = IccCard.State.READY;
  67.  
    }
  68.  
    // storage
  69.  
    mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
  70.  
    mStorageManager.registerListener(mStorageNotification);
  71.  
     
  72.  
    // TTY status
  73.  
    mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0, null);
  74.  
    mService.setIconVisibility("tty", false);
  75.  
     
  76.  
    // Cdma Roaming Indicator, ERI
  77.  
    mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_0, 0, null);
  78.  
    mService.setIconVisibility("cdma_eri", false);
  79.  
     
  80.  
    // bluetooth status
  81.  
    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
  82.  
    int bluetoothIcon = R.drawable.stat_sys_data_bluetooth;
  83.  
    if (adapter != null) {
  84.  
    mBluetoothEnabled = (adapter.getState() == BluetoothAdapter.STATE_ON);
  85.  
    if (adapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTED) {
  86.  
    bluetoothIcon = R.drawable.stat_sys_data_bluetooth_connected;
  87.  
    }
  88.  
    }
  89.  
    mService.setIcon("bluetooth", bluetoothIcon, 0, null);
  90.  
    mService.setIconVisibility("bluetooth", mBluetoothEnabled);
  91.  
     
  92.  
    /*add code for adding headset icon in statusbar.*/
  93.  
    mService.setIcon("headset", R.drawable.stat_sys_headset, 0, null);
  94.  
    mService.setIconVisibility("headset", false);
  95.  
    //end
  96.  
     
  97.  
    // Alarm clock
  98.  
    mService.setIcon("alarm_clock", R.drawable.stat_sys_alarm, 0, null);
  99.  
    mService.setIconVisibility("alarm_clock", false);
  100.  
     
  101.  
    // Sync state
  102.  
    mService.setIcon("sync_active", R.drawable.stat_sys_sync, 0, null);
  103.  
    mService.setIcon("sync_failing", R.drawable.stat_sys_sync_error, 0, null);
  104.  
    mService.setIconVisibility("sync_active", false);
  105.  
    mService.setIconVisibility("sync_failing", false);
  106.  
     
  107.  
    // volume
  108.  
    mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0, null);
  109.  
    mService.setIconVisibility("volume", false);
  110.  
    updateVolume();
  111.  
    }
  112.  
     
  113.  
     
  114.  
    /*add code for adding headset icon in statusbar.*/
  115.  
    private final void updateHeadsetState(Intent intent) {
  116.  
    boolean mIsHeadsetOn = (intent.getIntExtra("state", 0) == 1);
  117.  
    Slog.v(TAG, "updateHeadsetState: HeadsetState: " + mIsHeadsetOn);
  118.  
     
  119.  
    mService.setIconVisibility("headset", mIsHeadsetOn);
  120.  
    }

在frameworksasecore es esvaluesconfig.xml中加入耳机图标控制字段(headset):

  1.  
    <string-array name="config_statusBarIcons">
  2.  
    <item><xliff:g id="id">ime</xliff:g></item>
  3.  
    <item><xliff:g id="id">sync_failing</xliff:g></item>
  4.  
    <item><xliff:g id="id">sync_active</xliff:g></item>
  5.  
    <item><xliff:g id="id">gps</xliff:g></item>
  6.  
    <item><xliff:g id="id">bluetooth</xliff:g></item>
  7.  
    <item><xliff:g id="id">nfc</xliff:g></item>
  8.  
    <item><xliff:g id="id">tty</xliff:g></item>
  9.  
    <item><xliff:g id="id">speakerphone</xliff:g></item>
  10.  
    <item><xliff:g id="id">mute</xliff:g></item>
  11.  
    <item><xliff:g id="id">volume</xliff:g></item>
  12.  
    <item><xliff:g id="id">wifi</xliff:g></item>
  13.  
    <item><xliff:g id="id">cdma_eri</xliff:g></item>
  14.  
    <item><xliff:g id="id">phone_signal_second_sub</xliff:g></item>
  15.  
    <item><xliff:g id="id">data_connection</xliff:g></item>
  16.  
    <item><xliff:g id="id">phone_evdo_signal</xliff:g></item>
  17.  
    <item><xliff:g id="id">phone_signal</xliff:g></item>
  18.  
    <item><xliff:g id="id">battery</xliff:g></item>
  19.  
    <item><xliff:g id="id">alarm_clock</xliff:g></item>
  20.  
    <item><xliff:g id="id">secure</xliff:g></item>
  21.  
    <item><xliff:g id="id">clock</xliff:g></item>
  22.  
    <item><xliff:g id="id">headset</xliff:g></item>
  23.  
     
  24.  
    </string-array>

因为所加代码中的 mService.setIcon和mService.setIconVisibility最终会调用到StatusBarManagerService,它的构造函数有mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons));语句,找到config_statusBarIcons所在的配置文件为config.xml。如果没加,会再seticon(StatusBarManagerService类里)函数里

3:Android--隐藏状态栏图标

目前状态栏图标有通知图标和系统图标
通知图标主要是指各应用发过来的通知,比如未接电话,截图,后台播放音乐等,系统图标主要有蓝牙,耳机,wifi,数据流量,时间和电池...

1,不显示通知图标,
在/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java中
public void updateNotificationIcons {

     for (int i = 0; i < N; i++) {
            NotificationData.Entry ent = activeNotifications.get(i);
  +          final String pkg = ent.notification.getPackageName();
  +           android.util.Log.d("StatusBarIconController","pkg========"+pkg);

            //比如如果包名不是收音机的,就不显示图标
  +        if (!pkg.contains("com.android.fmradio")) {
  +              continue;
            }
            if (notificationData.isAmbient(ent.key)
                    && !NotificationData.showNotificationEvenIfUnprovisioned(ent.notification)) {
                continue;
            }
}

2.不显示系统图标,系统图标的显示是在以下文件,比如蓝牙,wifi,耳机等
/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/
PhoneStatusBarPolicy.java

将不要显示图标,将setIconVisibility()改为false即可,比如,如果不要闹钟图标
private void updateAlarm() {
        ....
- - -       mService.setIconVisibility(SLOT_ALARM_CLOCK, mCurrentUserSetup && hasAlarm);

+++ mService.setIconVisibility(SLOT_ALARM_CLOCK, false);
    }
3,系统图标中比较特殊的时间和电池在
/frameworks/base/packages/SystemUI/res/layout/status_bar.xml
<com.android.systemui.statusbar.policy.Clock
                android:id="@+id/clock"
                android:textAppearance="@style/TextAppearance.StatusBar.Clock"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:singleLine="true"
                android:paddingStart="7dp"
                android:gravity="center_vertical|start"
+++            android:visibility="gone"   //时间
                />
/frameworks/base/packages/SystemUI/res/layout/system_icons.xml

<com.android.systemui.BatteryMeterView android:id="@+id/battery"
        android:layout_height="14.5dp"
        android:layout_width="9.5dp"
+++    android:visibility="gone"      电池
        android:layout_marginBottom="@dimen/battery_margin_bottom"/>

4:android 5.1 usb调试默认关闭设置方法

packages/apps/Provision/src/com/android/provision/DefaultActivity.java 
在该文件中加入下面的代码:

 
    

  1.  
     if (!android.os.SystemProperties.getBoolean("ro.inet.adb_enabled",true)) {
  2.  
               Settings.Secure.putInt(getContentResolver(), Settings.Secure.ADB_ENABLED, 0);
  3.  
           }



同时在system.prop中添加:

    ro.inet.adb_enabled=false
 

5:【Audio】【音量曲线】【响度】如何修改音量曲线?

对应场景可能是:
当把媒体音量调到最小一级时,喇叭/耳机音量仍然很大,如何解决?

  如图1所示:
1. 音量曲线是通过四个点绘制而成,点(x,y)坐标中,x取值范围是0->100以内的整数,y是-100->0以内的有一位小数的任意数值,并且随着x数值的增大,y也增大,也就是说该曲线是递增曲线。
2. y数值与具体增益值线性相关。但其实真正增益amplification与y数值具体对应关系如下代码所描述:

安卓7/8/9配置修改位置为:
frameworks/av/services/audiopolicy/config/ default_volume_tables.xml

如喇叭音量曲线可以修改以下代码段:
    <!-- Default is Speaker Media Volume Curve -->
        <point>1,-3000</point>
        <point>33,-2200</point>
        <point>66,-1200</point>
        <point>100,0</point>
    </reference>

如图1所示:
1. 音量曲线是通过四个点绘制而成,点(x,y)坐标中,x取值范围是0->100以内的整数,y是-100->0以内的有一位小数的任意数值,并且随着x数值的增大,y也增大,也就是说该曲线是递增曲线。
2. y数值与具体增益值线性相关。但其实真正增益amplification与y数值具体对应关系如下代码所描述:

安卓7/8/9配置修改位置为:
frameworks/av/services/audiopolicy/config/ default_volume_tables.xml

如喇叭音量曲线可以修改以下代码段:
    <!-- Default is Speaker Media Volume Curve -->
        <point>1,-3000</point>
        <point>33,-2200</point>
        <point>66,-1200</point>
        <point>100,0</point>
    </reference>

 

6:【audio】【底噪】【功放延迟关闭问题】如何解决在关闭喇叭后喇叭还是有几秒底噪问题?

 按键音或音乐暂停后有3S底噪,怎么办?2017.05.06
这个是平台端参数设定,可修改参数3s延迟问题可参考旧版本修改方法。如果找不到,可咨询MTK平台修改。
修改代码路径为: Framworks/av/services/audioflinger/AudioFlinger.h,把AudioFlinger.h文件里面的
static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(0)//3 
默认是3,需将3改成0s。

 7:【audio】【usb】【UAC】如何在高通平台关闭usb audio驱动功能?

使用usb camera的时候由于误选经常会选择到UAC Camera导致系统默认声卡的功能异常,如无法录音播放语音等,可以通过以下方式关闭usb audio驱动功能。
diff --git a/kernel/msm-3.18/sound/Makefile b/kernel/msm-3.18/sound/Makefile
index ce9132b..2c8b762 100644
--- a/kernel/msm-3.18/sound/Makefile
+++ b/kernel/msm-3.18/sound/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_SOUND) += soundcore.o
 obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o
 obj-$(CONFIG_SOUND_PRIME) += oss/
 obj-$(CONFIG_DMASOUND) += oss/
-obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/
+obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/
        firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/
 obj-$(CONFIG_SND_AOA) += aoa/

8:【Modem】【GPS】GPS定位基础术语介绍 

1、GPS冷启动:(1)初次使用;(2)电池耗尽导致星历信息丢失;(3)关机状态下将接收机移动1000公里以上距离。
2、GPS温启动:距离上次定位的时间超过两个小时的启动。
3、GPS热启动:距离上次定位的时间小于两个小时的启动。
4、AGPS:辅助GPS定位,一般基站辅助,可大大缩短冷启动时间,由于 google supl server在国内不能用,需要客户使用第三方厂商的位置服务器,比如国内千寻公司。由于AGPS主要以GPS定位为主,并不能改善室内定位的效果。
5、NLP:网络定位,直接使用第三方SDK获取现成定位数据,开发者可直接下载百度或高德的SDK进行开发,方法简单。

9:android:关掉系统的 安全模式

 当 Android 设备在安全模式(Safe Mode)下工作时,任何的第三方应用程序或相关文件(主要为apk应用程序文件)都不可以使用,但可以使用 Android 设备的任务管理器选项进行卸载或管理应用程序,即Android 设备的操作系统或软件或相关文件出现问题导致系统进不了正常界面或不能正常启动系统时,则可以将设备进入安全模式(Safe Mode)卸载或管理原系统以外安装的应用程序或驱动文件或其他第三方相关文件,当在安全模式(Safe Mode)下完全卸载或管理了相关第三方安装的应用程序仍然不可以解决问题后,再进行安装或升级或更新操作系统或其他方法来解决问题。进入安全模式时,主界面的左下方显示“安全模式”或“Safe Mode”提示。安全模式进入方法:机器启动后,在开机动画前, 按住 Menu 或 音量减键至开机完成,就可以进入安全模式。安全模式退出方法:若需要退出安全模式,当且Android 设备在没有进行过特别使用或使用不当时(设备未使用非原装充电器充电,设备未拆过机等),将设备关机,然后重新开机,即可以退出安全模式,正常进入系统.系统检测是否进入安全模式的调用实现列出:frameworks/base/services/java/com/android/server/SystemServer.java frameworks/base/services/java/com/android/server/wm/WindowManagerService.javaframeworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

  1.  
    +++ frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
  2.  
    @@ -7532,7 +7532,7 @@ public class WindowManagerService extends IWindowManager.Stub
  3.  
    Log.i(TAG, "SAFE MODE not enabled");
  4.  
    }
  5.  
    mPolicy.setSafeMode(mSafeMode);
  6.  
    - return mSafeMode;
  7.  
    + return false;
  8.  
    }
  9.  
     
  10.  
    public void displayReady() {

10:google全家桶套餐下载地址 

https://opengapps.org/

11:【Android】在SElinux下 如何获得对一个内核节点的访问权限 

Android 5.0下,因为采取了SEAndroid/SElinux的安全机制,即使拥有root权限,或者对某内核节点设置为777的权限,仍然无法在JNI层访问。
本文将以用户自定义的内核节点/dev/wf_bt为例,手把手教会读者如何在JNI层获得对该节点的访问权限。

第一步:找到需要访问该内核节点的进程(process),笔者自己这个节点由system_server进程来访问

第二步:打开文件AndroidL/android/external/sepolicy/file_contexts.be 仿照这个文件里的写法,为你的节点定义一个你想要的名字:

在CODE上查看代码片派生到我的代码片

   /dev/tegra.* u:object_r:video_device:s0 
   /dev/tf_driver u:object_r:tee_device:s0 
   /dev/tty u:object_r:owntty_device:s0 
   /dev/tty[0-9]* u:object_r:tty_device:s0 
   # We add here 
   /dev/wf_bt u:object_r:wf_bt_device:s0 
wf_bt_device是自定义,其他左右两边的内容都和上面的范例一致。

第三步:打开文件AndroidL/android/external/sepolicy/device.te 仿照这个文件里的写法,将刚刚第二步写的wf_bt_device声明为dev_type:

在CODE上查看代码片派生到我的代码片

   # Device types 
   type device, dev_type, fs_type; 
   type alarm_device, dev_type, mlstrustedobject; 
   type adb_device, dev_type; 
   type ashmem_device, dev_type, mlstrustedobject; 
   type audio_device, dev_type; 
   type binder_device, dev_type, mlstrustedobject; 
   type block_device, dev_type; 
   # We add here 
   type wf_bt_device, dev_type; 

第四步: AndroidL/android/external/sepolicy/目录下很多.te文件都是以进程名来结尾的,比如有针对surfaceflinger进程的surfaceflinger,有针对vold进程的vold.te, 刚刚从第一步得到,这个节点是由system_server进程来访问,所以,我们找到system_server.te打开,加入允许这个进程对/dev/wf_bt的读写权限,

在CODE上查看代码片派生到我的代码片

   # Read/Write to /proc/net/xt_qtaguid/ctrl and and /dev/xt_qtaguid. 
   allow system_server qtaguid_proc:file rw_file_perms; 
   allow system_server qtaguid_device:chr_file rw_file_perms; 
     
   # chr_file表示字符设备文件,如果是普通文件用file,目录请用dir 
   # rw_file_perms代表读写权限 
   allow system_server wf_bt_device:chr_file rw_file_perms; 
这句话的意思是:允许system_server进程拥有对wf_bt_device的这个字符设备的读写权限。 改了这些之后,你就可以make installclean;make -j16编译image来验证权限是否获取成功。

fd =open("/dev/wf_bt",O_RDONLY | O_NOCTTY); 就可以成功访问了。

在framework写一个文件,比如:cache/hideapp.txt 但是在launcher2里是不能访问的,会报一个FileNotFoundException的异常。 这也是没权限访问的原因。 因此接下来就添加权限 在AndroidL/android/external/sepolicy/目录下, 首先在file_contexts里添加

/cache/hideapp.txt u:object_r:meig_pub_file:s0
然后再在file.te里添加

type meig_pub_file, file_type; 

12:如何区分欧标和美标耳机

1. 使用错误标准的耳机导致异常
当使用错误标准耳机时,会遇到以下情况:
1.音频被抑制,左右声道的声音丢失、杂音、没有立体感
2.麦克风不能正常工作
3.耳机的挂断、接听按键不能正常工作。

2. Pin脚顺序
目前国际上通用的四孔手机耳机接口标准有两个,一个是OMTP的标准,一个是CTIA的标准。
CTIA(美标)的3.5mm接口:插针接法是左声道-右声道-地线-麦克风。
OMTP(欧标)的3.5mm接口:插针接法是左声道-右声道-麦克风-地线。
其中欧标耳机插针如上图所示。

3. 测试方法
如何使用万用表检测耳机标准
从右到左,暂定为1、2、3、4脚。
如何运用万用表区分耳机是美标还是欧标?
原理其实就是测量左声道对地电阻
将万用表调节到阻抗测量功能,量程选在100欧姆,
当测量上图中的1和3脚时,阻抗在32欧姆左右,则为美标耳机。
当测量上图中的1和4脚时,阻抗在32欧姆左右,则为欧标耳机。
 

13: 高通耳机增益简单调试方案

1. 对应代码文件位置
platform filepath
msm8917 hardware/qcom/audio/configs/msm8937/mixer_paths_qrd_sku2.xml
msm8937 hardware/qcom/audio/configs/msm8937/mixer_paths_qrd_sku2.xml
msm8953 hardware/qcom/audio/configs/msm8953/mixer_paths_qrd_sku3.xml
msm8909 device/qcom/msm8909/mixer_paths_skua.xml

2. 音频路径配置以及调试参数确认
1) 默认情况下,耳机的音频路径是以CDC_HPH_R和CDC_HPH_L同时作为音源
   <path name="headphones">
       <ctl name="MI2S_RX Channels" value="Two" />
       <ctl name="RX1 MIX1 INP1" value="RX1" />
       <ctl name="RX2 MIX1 INP1" value="RX2" />
       <ctl name="RDAC2 MUX" value="RX2" />
       <ctl name="HPHL" value="Switch" />
       <ctl name="HPHR" value="Switch" />
       <ctl name="RX1 Digital Volume" value="84" />
   </path>
调试参数为:"RX1 Digital Volume"和"RX2 Digital Volume"
2) 如果耳机的音频路径只以CDC_HPH_R作为音源
   <path name="headphones">
       <ctl name="MI2S_RX Channels" value="One" />
       <ctl name="RX2 MIX1 INP1" value="RX1" />
       <ctl name="RDAC2 MUX" value="RX2" />
       <ctl name="HPHR" value="Switch" />
       <ctl name="Ext Spk Switch" value="On" />
   </path>
调试参数为:"RX2 Digital Volume"
3) 如果耳机的音频路径只以CDC_HPH_L作为音源
   <path name="headphones">
       <ctl name="MI2S_RX Channels" value="One" />
       <ctl name="RX1 MIX1 INP1" value="RX1" />
       <ctl name="HPHL" value="Switch" />
       <ctl name="Ext Spk Switch" value="On" />
   </path>
调试参数为:"RX1 Digital Volume"

3. 调试参数介绍
注意:RXn Digital Volume
对应的n取值范围是1、2和3。
对应的XX取值范围为0-124,"0" means -84dB, "84" means0dB, and "124" means +40dB。

4. 验证RXn Digital Volume对应的XX最合适取值,可以在播放音乐时,在adb窗口通过下列命令实时调整:
adb root
adb shell
tinymix "RXn Digital Volume" "84"
tinymix "RXn Digital Volume" "99"
tinymix "RXn Digital Volume" "XX"
注意:如果耳机走的是默认音频路径,请同步执行命令对"RX1 Digital Volume"和"RX2 Digital Volume"进行配置,如下所示:
tinymix "RX1 Digital Volume" "99"
tinymix "RX2 Digital Volume" "99"

5. 修改方法(以msm8917平台为例)
(1)导入配置,重启生效
adb root
adb remount
adb push mixer_paths_qrd_sku2.xml /etc/mixer_paths_qrd_sku2.xml
adb reboot
(2)同步修改hardware/qcom/audio/configs/msm8937/mixer_paths_qrd_sku2.xml,编译system.img,重新下载生效
 

14:高通工具acdb音频配置文件使用方案 

方法1.push到机器特定路径下,重启机器验证
adb root
adb remount
msm8909: adb push QRD_Speaker_cal.acdb /etc/acdbdata/QRD/
msm8916: adb push QRD_Speaker_cal.acdb /etc/acdbdata/QRD/
msm8917: adb push QRD_Speaker_cal.acdb /etc/acdbdata/QRD/
msm8937: adb push QRD_SKU2_Speaker_cal.acdb /etc/acdbdata/QRD/
msm8939: adb push QRD_SKUL_Speaker_cal.acdb /etc/acdbdata/QRD/
msm8953: adb push QRD_Speaker_cal.acdb /etc/acdbdata/QRD/
adb shell sync
adb reboot
注意:如果无法push,先执行adb disable-verity,然后重启机器,再重复以上操作。
方法2. 编译system镜像下载烧录
msm8909: 把QRD_Speaker_cal.acdb重命名为Speaker_cal.acdb,替换到LA.BR.1.2.7-06210-8x09.0vendorqcomproprietarymm-audioaudcalfamily-bacdbdata8909QRD代码路径下,重新编译system.img即可。
msm8916: 把QRD_Speaker_cal.acdb重命名为Speaker_cal.acdb,替换到LA.BR.1.2.4-05310-8x16.0vendorqcomproprietarymm-audioaudcalfamily-bacdbdata8916QRD代码路径下,重新编译system.img即可。
msm8917: 把QRD_Speaker_cal.acdb重命名为Speaker_cal.acdb,替换到LA.UM.5.6vendorqcomproprietarymm-audioaudcalfamily-bacdbdata8937QRD代码路径下,重新编译system.img即可。
msm8937: 把QRD_SKU2_Speaker_cal.acdb重命名为Speaker_cal.acdb,替换到LA.UM.5.6vendorqcomproprietarymm-audioaudcalfamily-bacdbdata8937QRDmsm8952-sku2-snd-card代码路径下,重新编译system.img即可。
msm8939: 把QRD_SKUL_Speaker_cal.acdb重命名为Speaker_cal.acdb,替换到LA.BR.1.2.4-05310-8x16.0vendorqcomproprietarymm-audioaudcalfamily-bacdbdata8916QRDmsm8939-snd-card-skul代码路径下,重新编译system.img即可。
msm8953: 把QRD_Speaker_cal.acdb重命名为Speaker_cal.acdb,替换到LA.UM.5.6vendorqcomproprietarymm-audioaudcalfamily-bacdbdata8953QRD代码路径下,重新编译system.img即可。

15:屏蔽所有物理按键

frameworksaseservicescorejavacomandroidserverwmWindowManagerService.java

computeScreenConfigurationLocked 方法将hardKeyboardAvailable改为false。

boolean hardKeyboardAvailable = false;

 16: vendor下的应用第一次自启

frameworksaseservicescorejavacomandroidserveramActivityManagerService.java    6938行左右
for (int i=0; i<mStartedUsers.size(); i++) {
                    UserStartedState uss = mStartedUsers.valueAt(i);
                    if (uss.mState == UserStartedState.STATE_BOOTING) {
                        uss.mState = UserStartedState.STATE_RUNNING;
                        final int userId = mStartedUsers.keyAt(i);
                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
                        broadcastIntentLocked(null, null, intent, null,
                                new IIntentReceiver.Stub() {
                                    @Override
                                    public void performReceive(Intent intent, int resultCode,
                                            String data, Bundle extras, boolean ordered,
                                            boolean sticky, int sendingUser) {
                                        synchronized (ActivityManagerService.this) {
                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
                                                    true, false);
                                            /// M: Mobile Management Feature @{
                                            mAmPlus.monitorBootReceiver(false, "Normal Bootup End");
                                            /// @}
                                        }
                                    }
                                },
                                0, null, null,
                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
                                userId);
                    }
                }
 

intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);下添加一行intent.setFlags(32);

 17:Android framework 修改系统声音最大值默认值以及系统亮度默认值最大值位置 

(Android4.4.3),找到文件代码位置

修改系统音量:

文件位置:/frameworks/base/media/java/android/media/

这里要修改两个文件:

1.修改音量最大值 :修改AudioManager.java下的DEFAULT_STREAM_VOLUME值即可。

2.修改音量默认值:修改AudioService.java下的MAX_STREAM_VOLUME即可。

修改系统亮度:

文件位置:/frameworks/base/core/res/res/values/config.xml

1.最大值:config_screenBrightnessSettingMaximum

2.最小值:config_screenBrightnessSettingMinmum

3.默认值:config_screenBrightnessSettingDefault

18:消除原生Android网络状态上的惊叹号

谷歌在Android5.0之后的版本加入了CaptivePotalLogin服务。本服务的功能是检查网络连接互联网情况,主要针对于Wi-Fi,不让Android设备自动连接那些不能联网的无线热点,白白耗电。
该服务的原理就是让接入无线热点后,测一下网站connectivitycheck.gstatic.com的联通情况。
但对于不能访问谷歌服务器的地区,问题就来了:

  1. 如果谷歌(谷歌服务)认为WiFi网络无法联网,就不会自动连接到该WiFi热点。而且如果设备有移动网络可用,就会自动切换到2G/3G/LTE。并且让WiFi网络的标志上面显示感叹号标志。

  2. 出现感叹号的同时,该服务会一直试探服务器,直到联通为止。该过程会消耗流量和电量,甚至导致部分设备无法休眠。

  3. 这个感叹号会使广大强迫症晚期患者无法接受。

对于Android Source开发的同学,最好的解决办法自然是修改源码:
方案1:更换测试地址
frameworks/base/packages/SettingsProvider/res/values/defaults.xml:

  1.  
    diff --git a/frameworks/base/packages/SettingsProvider/res/values/defaults.xml b/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
  2.  
    index bede17d..508d384 100644
  3.  
    --- a/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
  4.  
    +++ b/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
  5.  
    @@ -215,5 +215,5 @@
  6.  
    <bool name="def_guest_user_enabled">true</bool>
  7.  
     
  8.  
    <!-- Default for Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED -->
  9.  
    - <integer name="def_captive_portal_detection_enabled" translatable="false">1</integer>
  10.  
    + <integer name="def_captive_portal_detection_enabled" translatable="false">0</integer>
  11.  
    </resources>

 18:件上是单麦但是代码中默认配置是双麦属性的问题

心板业务线上的客户经常遇到这种设计问题,硬件上是单麦但是代码中默认配置是双麦属性的问题。
这里讲解下如何调整单双麦属性配置以及该配置对设备音效的影响?

1. 代码位置
8909平台:deviceqcommsm8909system.prop
8937平台:hardwareqcomaudioconfigsmsm8937msm8937.mk
8953平台:hardwareqcomaudioconfigsmsm8953msm8953.mk


2. 属性解读
以下属性的意义:
ro.qc.sdk.audio.fluencetype可以配置为none,fluence。其中fluence是高通提供的是双麦降噪音效FLUENCEV5。
persist.audio.fluence.voicecall可以配置true和false,其中只有当ro.qc.sdk.audio.fluencetype配置为fluence且persist.audio.fluence.voicecall配置为true,对应听筒通话模式走双麦。
persist.audio.fluence.voicerec=false可以配置true和false,其中只有当ro.qc.sdk.audio.fluencetype配置为fluence且persist.audio.fluence.voicerec配置为true,对应通话录音功能走双麦,默认配置为false,无需调整。
persist.audio.fluence.audiorec=false可以配置true和false,其中只有当ro.qc.sdk.audio.fluencetype配置为fluence且persist.audio.fluence.audiorec配置为true,对应普通录音功能走双麦。
persist.audio.fluence.speaker=false可以配置true和false,其中只有当ro.qc.sdk.audio.fluencetype配置为fluence且persist.audio.fluence.speaker配置为true,对应免提通话模式走双麦。
注意,这里有个小技巧,比如ro.qc.sdk.audio.fluencetype配置为fluence后,也是可以调整普通录音功能或者免提通话模式或者听筒通话模式的一个或者多个使用的单麦的。
当然只有这样音效更好的话才需要这么配置。

3. 属性名称变更问题
在安卓8和安卓9系统中,属性名称有所变更。
对应变更如下:
ro.vendor.audio.sdk.fluencetype
persist.vendor.audio.fluence.voicecall
persist.vendor.audio.fluence.voicerec
persist.vendor.audio.fluence.audiorec
persist.vendor.audio.fluence.speaker

4. 属性配置
当硬件上是双麦,但是配置为单麦属性的话,既会导致资源浪费,也不利于音效优化。
反过来,如果硬件上是单麦但是软件上配置为双麦属性的话,音效必然不会很好。

  19:Android系统修改所有应用能读写SD卡

需要Android源码/frameworksasedataetcplatform.xml
找到
<permission name="android.permission.WRITE_EXTERNAL_STORAGE">
<group gid="sdcard_rw" />

修改为

<permission name="android.permission.WRITE_EXTERNAL_STORAGE">
<group gid="sdcard_rw" />

<group gid="media_rw" />

保存,将系统烧录到板中即可。 

20:Android 6.0以上 默认允许应用弹窗申请权限 

方案如下:
在 ap/packages/apps/PackageInstaller/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java 中;
在 onCreate 中,源码为

  1.  
    DevicePolicyManager devicePolicyManager = getSystemService(DevicePolicyManager.class);
  2.  
    final int permissionPolicy = devicePolicyManager.getPermissionPolicy(null);

改为:

  1.  
    DevicePolicyManager devicePolicyManager = getSystemService(DevicePolicyManager.class);
  2.  
    // modify 
  3.  
    final int permissionPolicy = DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT;

21:Android 系统增加默认属性 Settings.System.putInt

这种方式会保存变量到Settings 数据库中,飞行模式等的开关就是用这种方式实现的。

首先需要定义一个系统属性值

路径:frameworks/base/core/java/android/provider/Settings.java

 public static final String  ACTION_MINTECH_NOTIFY_SETTINGS =     "android.settings.mintech.notify";(自定义)

在public static final String[] SETTINGS_TO_BACKUP  数组中添加:

  

  1.  
    public static final String[] SETTINGS_TO_BACKUP = {
  2.  
    STAY_ON_WHILE_PLUGGED_IN, // moved to global
  3.  
    WIFI_USE_STATIC_IP,
  4.  
    WIFI_STATIC_IP,
  5.  
    WIFI_STATIC_GATEWAY,
  6.  
    WIFI_STATIC_NETMASK,
  7.  
    ACTION_MINTECH_NOTIFY_SETTINGS, //自定义添加的
  8.  
    WIFI_STATIC_DNS1,
  9.  
    WIFI_STATIC_DNS2,
  10.  
    WIFI_AUTO_CONNECT_TYPE,
  11.  
    BLUETOOTH_DISCOVERABILITY,
  12.  
    BLUETOOTH_DISCOVERABILITY_TIMEOUT,
  13.  
    DIM_SCREEN,
  14.  
    SCREEN_OFF_TIMEOUT,
  15.  
    SCREEN_BRIGHTNESS,
  16.  
    SCREEN_BRIGHTNESS_MODE,
  17.  
    SCREEN_AUTO_BRIGHTNESS_ADJ,
  18.  
    VIBRATE_INPUT_DEVICES,
  19.  
    MODE_RINGER_STREAMS_AFFECTED,
  20.  
    VOLUME_VOICE,
  21.  
    VOLUME_SYSTEM,
  22.  
    VOLUME_RING,
  23.  
    VOLUME_MUSIC,
  24.  
    VOLUME_ALARM,
  25.  
    VOLUME_NOTIFICATION,

需要import android.provider.Settings;

1)获取方法如下:

  1.  
    @Override
  2.  
    public void onResume()
  3.  
    {
  4.  
    super.onResume();
  5.  
    if(Settings.System.getInt(getContentResolver(), Settings.System.XXXX,0)==1)
  6.  
    {
  7.  
    //写逻辑
  8.  
     
  9.  
       }else
  10.  
     
  11.  
          //写逻辑
  12.  
    }
  13.  
    }

2)设置

  1.  
    if (/**设置逻辑判断*/) {
  2.  
     
  3.  
    Settings.System.putInt(getContentResolver(), Settings.System.XXX, 1);
  4.  
     
  5.  
     } else {
  6.  
     
  7.  
             Settings.System.putInt(getContentResolver(),Settings.System.VIVIEN_FASTFOOD, 0);
  8.  
    }

21:Android 系统USER版本去掉 USB插入调试确认框

                                                           

  修改路径:  xframeworksasepackagesSystemUIsrccomandroidsystemuiusbUsbDebuggingActivity.java

  1.  
    public class UsbDebuggingActivity extends AlertActivity
  2.  
    implements DialogInterface.OnClickListener {
  3.  
    private static final String TAG = "UsbDebuggingActivity";
  4.  
     
  5.  
    private CheckBox mAlwaysAllow;
  6.  
    private UsbDisconnectedReceiver mDisconnectedReceiver;
  7.  
    private String mKey;
  8.  
     
  9.  
    @Override
  10.  
    public void onCreate(Bundle icicle) {
  11.  
    super.onCreate(icicle);
  12.  
     
  13.  
    if (SystemProperties.getInt("service.adb.tcp.port", 0) == 0) {
  14.  
    mDisconnectedReceiver = new UsbDisconnectedReceiver(this);
  15.  
    }
  16.  
     
  17.  
    Intent intent = getIntent();
  18.  
    String fingerprints = intent.getStringExtra("fingerprints");
  19.  
    mKey = intent.getStringExtra("key");
  20.  
     
  21.  
    if (fingerprints == null || mKey == null) {
  22.  
    finish();
  23.  
    return;
  24.  
    }
  25.  
     
  26.  
    //1:去掉弹窗的初始化
  27.  
    /* final AlertController.AlertParams ap = mAlertParams;
  28.  
    ap.mTitle = getString(R.string.usb_debugging_title);
  29.  
    ap.mMessage = getString(R.string.usb_debugging_message, fingerprints);
  30.  
    ap.mPositiveButtonText = getString(android.R.string.ok);
  31.  
    ap.mNegativeButtonText = getString(android.R.string.cancel);
  32.  
    ap.mPositiveButtonListener = this;
  33.  
    ap.mNegativeButtonListener = this;
  34.  
     
  35.  
    // add "always allow" checkbox
  36.  
    LayoutInflater inflater = LayoutInflater.from(ap.mContext);
  37.  
    View checkbox = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
  38.  
    mAlwaysAllow = (CheckBox)checkbox.findViewById(com.android.internal.R.id.alwaysUse);
  39.  
    mAlwaysAllow.setText(getString(R.string.usb_debugging_always));
  40.  
    ap.mView = checkbox;
  41.  
     
  42.  
    setupAlert();*/
  43.  
     
  44.  
    /:2:将onclik事件的代码移植过来 并设置 allow & alwaysAllow 为true
  45.  
    boolean allow = true;// (which == AlertDialog.BUTTON_POSITIVE);
  46.  
    boolean alwaysAllow = true;//allow && mAlwaysAllow.isChecked();
  47.  
    try {
  48.  
    IBinder b = ServiceManager.getService(USB_SERVICE);
  49.  
    IUsbManager service = IUsbManager.Stub.asInterface(b);
  50.  
    if (allow) {
  51.  
    service.allowUsbDebugging(alwaysAllow, mKey);
  52.  
    } else {
  53.  
    service.denyUsbDebugging();
  54.  
    }
  55.  
    } catch (Exception e) {
  56.  
    Log.e(TAG, "Unable to notify Usb service", e);
  57.  
    }
  58.  
    finish();
  59.  
    }
  60.  
     
  61.  
     
  62.  
    //...省略部分代码
  63.  
     
  64.  
    @Override
  65.  
    public void onClick(DialogInterface dialog, int which) {
  66.  
    boolean allow = true;// (which == AlertDialog.BUTTON_POSITIVE);
  67.  
    boolean alwaysAllow = true;//allow && mAlwaysAllow.isChecked();
  68.  
    try {
  69.  
    IBinder b = ServiceManager.getService(USB_SERVICE);
  70.  
    IUsbManager service = IUsbManager.Stub.asInterface(b);
  71.  
    if (allow) {
  72.  
    service.allowUsbDebugging(alwaysAllow, mKey);
  73.  
    } else {
  74.  
    service.denyUsbDebugging();
  75.  
    }
  76.  
    } catch (Exception e) {
  77.  
    Log.e(TAG, "Unable to notify Usb service", e);
  78.  
    }
  79.  
    finish();
  80.  
    }
  81.  
    }

 参照代码中的第一点和第二点

22 编译 报错:error while loading shared libraries: libz.so.1: cannot open shared object file

arm-linux-gcc 交叉编译报错:
error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory
 
这个问题就是你64位的操作系统没有32位的类库,而android的SDK是要32位支持的,如果没装就只能是报上面的错!
 
解决:
# sudo apt-get update
# sudo apt-get install lib32z1

23高通平台关闭usb audio驱动功能?

使用usb camera的时候由于误选经常会选择到UAC Camera导致系统默认声卡的功能异常,如无法录音播放语音等,可以通过以下方式关闭usb audio驱动功能。
diff --git a/kernel/msm-3.18/sound/Makefile b/kernel/msm-3.18/sound/Makefile
index ce9132b..2c8b762 100644
--- a/kernel/msm-3.18/sound/Makefile
+++ b/kernel/msm-3.18/sound/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_SOUND) += soundcore.o
 obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o
 obj-$(CONFIG_SOUND_PRIME) += oss/
 obj-$(CONFIG_DMASOUND) += oss/
-obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/
+obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/
        firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/
 obj-$(CONFIG_SND_AOA) += aoa/

24 提高Android源代码的编译效率

 编译效率指南

1 开始编译

(1) 在 .bashrc文件末尾添加:

         export USE_CCACHE = 1

         echo export USE_CCACHE=1 >> ~/.bashrc

(2) 为了提高编译效率,设置编译器高速缓存:

        prebuilts/misc/linux-x86/ccache/ccache -M 50G

25Android编译环境常用的配置 

一:编译源码不要生成odex 问题: 
    1: 禁止apk生成odex: 修改../build/core/package.mk   
          LOCAL_DEX_PREOPT := ture  -> LOCAL_DEX_PREOPT := false
    2: 禁止jar包生成odex: 修改/build/core/java_library.mk  
          LOCAL_DEX_PREOPT := ture  ->  LOCAL_DEX_PREOPT:= false  

    3:禁止当前apk编译生成odex,在android.mk内增加:

          LOCAL_DEX_PREOPT := false

二:配置编译的时候使用的资源mdpi / hdpi / xhdpi

   进入build/core/product_config.mk文件:

# Default to medium-density assets.

# (Can be overridden in the device config,e.g.: PRODUCT_AAPT_CONFIG += hdpi)

PRODUCT_AAPT_CONFIG := $(strip

   $(PRODUCT_AAPT_CONFIG)

    $(if$(filter %dpi,$(PRODUCT_AAPT_CONFIG)),,mdpi))

PRODUCT_AAPT_PREF_CONFIG := $(strip$(PRODUCT_AAPT_PREF_CONFIG))

PRODUCT_AAPT_CONFIG := mdpi xlarge hdpi xhdpilarge

修改PRODUCT_AAPT_CONFIG := mdpi那么会有限编译mdpi下的资源文件,如果mdpi目录下没有对应的文件才会去hdpi下面去查找。
 

26:android 物联设备 省电开发之cpu降频 

1.CPU的工作频率

单位赫兹或者兆赫兹,具体含义不解释,说实话也不太清楚,不过可以确认一点的是,CPU的工作频率越高,耗电量越大,反之亦然。我们做这个模块省电的终极目标就是降低cpu的工作频率。

2.CPU的调控模式

英文词为:Governor,解释为调速器,控制器。大家都指导android的framework是基于linux平台的,那么cpu的管理体系这块也跟linux基本上一样,其中包括cat命令,和一些文件的读写配置都是基本上差不多的。Linux在管理CPU方面,提供了如下集中调控模式,分别为:

1.performance,这个不多说,就是将cpu的工作频率调整到最大模式,让cpu充分的工作。

2.powersave,将cpu的工作频率调整到节能模式,也就是这个模式下的cpu平率是最低的。

3.ondemand,定期检查负载。当负荷超越了阈值,设置的CPU运行以最高的频率。当负载低于相同的阈值,设置的CPU运行在下一个的最低频率。导致更少的延迟比。这个理解起来可能比较困难,我用白话大概解释一下,ondemand从字面翻译是“根据需求,按照需要”,cpu在工作的时候频率会在一个最大值和最小值之间波动,当负载提高时,该调控期会自动提高cpu的频率,反之亦然。“Causes less latency than the conservative governor.”这句话的意思是,该模式跟conservative相比,会导致更少的延迟。ok,那让我们再看看conservative是如何解释的。

4.conservative,改词用来形容保守的,守旧的。该模式与ondemand的最大区别在于,conservative模式不会立刻在负载增加的情况下将cpu频率调整到最大,他会调整到比目前频率稍微大的频段去工作,保守,实在是保守!所以换来的结果是,在某种极端情况下,该模式的延迟会大于ondemand。

5.usersapce,该模式将cpu的掌控权交给了用户态,也就是交给了应用程序,应用程序可以通过配置文件的方式修改cpu的频率信息,上面3种模式好比linux已经给你定义好的4种模式,userspace好比上面4种模式无法满足我的需求,我需要自定义!(由于第四种方式需要进行大量的文件操作和配置,本文不阐述了,与省电的目标相差比较远)

ok!我们了解了这5种省电模式,那么如何查看你的android手机当前运行在哪种模式下呢?当前的cpu运行的工作频率是多少呢?最大最小频率是多少?我如何修改模式呢?

其实很简单,android的cat命令都为我们解决了这些问题,首先要强调的是,必须要获得系统的root权限,才能进行以下操作。

第一步:adb shell 进入root 命令行模式

第二步 cd /sys/devices/system/cpu/cpu0/cpufreq 进入这个目录下面

第三步 ls

第四步 你能看见很多的文件

第五步 参考下面的命令,打一遍就清楚了,不过为了给傻瓜提供更好的服务,我还是尽可能的将命令的使用和作用写的详细。

/**
  * cpu cat命令大全
  * cat [%cpuFreqPath%]/cpuinfo_cur_freq   (当前cpu频率)
  * cat [%cpuFreqPath%]/cpuinfo_max_freq  (最大cpu频率)
  * cat [%cpuFreqPath%]/cpuinfo_min_freq  (最小cpu频率)
  * cat [%cpuFreqPath%]/related_cpus  (cpu数量标号,从0开始,如果是双核,结果为0,1)
  * cat [%cpuFreqPath%]/scaling_available_frequencies  (cpu所有可用频率)
  * cat [%cpuFreqPath%]/scaling_available_governors  (cpu所有可用调控模式)
  * cat [%cpuFreqPath%]/scaling_available_governors  (cpu所有可用调控模式)
  * cat [%cpuFreqPath%]/scaling_cur_freq  (?????)
  * cat [%cpuFreqPath%]/scaling_driver (调控驱动)
  * cat [%cpuFreqPath%]/scaling_governor (当前使用哪种调控模式)
  * cat [%cpuFreqPath%]/scaling_max_freq (?????)
  * cat [%cpuFreqPath%]/scaling_min_freq (?????)
  * cat [%cpuFreqPath%]/scaling_setspeed (?????)
  * cat [%cpuFreqPath%]/cpuinfo_transition_latency (变频延迟)
  */

熟悉了这些语法和密令之后,我们就可以很轻松的明白,如何省电了,无非就是将cpu降频嘛,把当前的调控模式调整为powersave就可以了嘛,不错,但是还不完全正确。

首先我先讲一下如何通过命令行改写当前的调控模式,很简单,一句命令:

echo "你想使用的调控模式" /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

但是因为手机出场适配等问题,有些机器上是没有powersave这个模式的,对了,你一定要确认当前手机是否有powersave这个模式,具体怎么看就在我上面给的命令大全里面,自己找!在没有powersave模式的情况下,我们只好通过更狠的方法修改cpu的频率,那就是直接改写cpu的频率,命令:

echo 2331000 > cpu0/cpufreq/scaling_min_freq  设置最小的工作频率,同时也可以设置最大的工作频率。

ok!设置cpu的频率的两种方式我基本上说清楚了,本质没什么差别。那么在实际java端的开发中,我们如何使用呢?

27:Android 插拔充电器增加声音

修改方法如下:
需要修改的文件路径如下
frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java。
在这个类中的如下代码增加修改:

   以下音源可以adb shell ->  cd system/media 下查看ogg音源并替换

   final Uri soundUri = Uri.parse("file://" + "/system/media/audio/notifications/F1_MissedCall.ogg");;

  1.  
    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
  2.  
    @Override
  3.  
    public void onReceive(Context context, Intent intent) {
  4.  
    String action = intent.getAction();
  5.  
    //省略若干 ........
  6.  
    //通过增加对如下广播的监听,实现需要的效果。注意增加广播的注册
  7.  
    else if (action.equals(Intent.ACTION_POWER_CONNECTED) || action.equals(Intent.ACTION_POWER_DISCONNECTED)){
  8.  
    android.util.Log.d("fxjsound","charging sounds");
  9.  
    final boolean enabled = Settings.Global.getInt(getContext().getContentResolver(),
  10.  
    Settings.Global.CHARGING_SOUNDS_ENABLED, 1) != 0;
  11.  
    if (enabled) {
  12.  
    final Uri soundUri = Uri.parse("file://" + "/system/media/audio/notifications/F1_MissedCall.ogg");;
  13.  
    if (soundUri != null) {
  14.  
    final Ringtone sfx = RingtoneManager.getRingtone(getContext(), soundUri);
  15.  
    if (sfx != null) {
  16.  
    sfx.setStreamType(AudioManager.STREAM_SYSTEM);
  17.  
    sfx.play();
  18.  
    }
  19.  
    }
  20.  
    }
  21.  
    }
  22.  
    // end
  23.  
    }
  24.  
    };


 

28:高通SPI屏视频播放RGB红蓝颜色反了,在电脑播放正常

--- a/kernel/drivers/video/msm/mdss/mdp3_ppp_data.c
+++ b/kernel/drivers/video/msm/mdss/mdp3_ppp_data.c
@@ -89,8 +89,10 @@ const uint32_t pack_patt_lut[MDP_IMGTYPE_LIMIT] = {
 };
 
 const uint32_t swapped_pack_patt_lut[MDP_IMGTYPE_LIMIT] = {
-       [MDP_RGB_565] = PPP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8),
-       [MDP_BGR_565] = PPP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8),
+       //[MDP_RGB_565] = PPP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8),
+       //[MDP_BGR_565] = PPP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8),
+       [MDP_RGB_565] = PPP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8),
+       [MDP_BGR_565] = PPP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8),
        [MDP_RGB_888] = PPP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8),
        [MDP_BGR_888] = PPP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8),
        [MDP_BGRA_8888] = PPP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R,

29: android5.1 按下power键 系统不休眠

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

  1.  
    @Override // Binder call
  2.  
    public void goToSleep(long eventTime, int reason, int flags) {
  3.  
    + if(true){
  4.  
    + return;
  5.  
    + }
  6.  
    if (eventTime > SystemClock.uptimeMillis()) {
  7.  
    throw new IllegalArgumentException("event time must not be in the future");
  8.  
    }

30: android5.1  电话白名单以及黑名单 逻辑

需求: 来电检测号码如果是设置好的黑名单则挂断,用户是察觉不到

修改文件 packages/services/Telecomm/src/com/android/server/telecom/CallsManager.java

  1.  
    /**
  2.  
    * Adds the specified call to the main list of live calls.
  3.  
    *
  4.  
    * @param call The call to add.
  5.  
    */
  6.  
    private void addCall(Call call) {
  7.  
    Log.v(this, "addCall(%s)", call);
  8.  
    //add code start
  9.  
    //判断是否来电
  10.  
    if(call.isIncoming()){
  11.  
    //获取设置好的电话通讯录
  12.  
    //这里使用系统数据库 并且使用逗号来分隔
  13.  
    String sysContacts = Settings.System.getString(mContext.getContentResolver(),"sys.smartship.contacts");
  14.  
    String[] split = sysContacts.split(",");
  15.  
    String phoneNumber = call.getNumber();
  16.  
    if(!"".equals(phoneNumber) || split.length != 0 )
  17.  
    {
  18.  
    for (int i = 0 ; i < split.length ; i++ ){
  19.  
    if( split[i].equals(phoneNumber)){
  20.  
    //有一样的号码则 挂断
  21.  
    call.disconnect();
  22.  
    break;
  23.  
    }
  24.  
    }
  25.  
    }
  26.  
    }// if(call.isIncoming())
  27.  
    //add code end
  28.  
    call.addListener(this);
  29.  
    mCalls.add(call);
  30.  
     
  31.  
    // TODO: Update mForegroundCall prior to invoking
  32.  
    // onCallAdded for calls which immediately take the foreground (like the first call).
  33.  
    for (CallsManagerListener listener : mListeners) {
  34.  
    listener.onCallAdded(call);
  35.  
    }
  36.  
    updateCallsManagerState();
  37.  
    }

31: android5.1-7.1- 8.1 电话接通成功并广播

定位代码文件

    packages/services/Telecomm/src/com/android/server/telecom/CallAudioManager.java

  1.  
    @Override
  2.  
    public void onCallStateChanged(Call call, int oldState, int newState) {
  3.  
    onCallUpdated(call);
  4.  
    //add code start
  5.  
    if(newState == CallState.ACTIVE){
  6.  
    Intent intent =new Intent();
  7.  
    intent.setAction("接通的广播");
  8.  
    mContext.sendBroadcast(intent);
  9.  
    }
  10.  
    //add code end
  11.  
    }

注 : 如果想知道是来电接通还是去电接通   通过Call 对象 call.isIncoming() 来判断

32: android 连接电脑时固定usb端口号 

diff --git a/device/qcom/common/rootdir/etc/init.qcom.usb.rc b/device/qcom/common/rootdir/etc/init.qcom.usb.rc

old mode 100644

new mode 100755

index eb45b64..88f6ff3

--- a/device/qcom/common/rootdir/etc/init.qcom.usb.rc

+++ b/device/qcom/common/rootdir/etc/init.qcom.usb.rc

@@ -27,7 +27,8 @@

 on init

     write /sys/class/android_usb/android0/f_rndis/wceis 1

-    write /sys/class/android_usb/android0/iSerial ${ro.serialno}

+    #write /sys/class/android_usb/android0/iSerial ${ro.serialno}

+       write /sys/class/android_usb/android0/iSerial 0

 on charger

     setprop sys.usb.config mass_storage

33:打开驱动DEBUG 日志

diff --git a/kernel/arch/arm/configs/msm8909-1gb_defconfig b/kernel/arch/arm/configs/msm8909-1gb_defconfig

index 8ff4053..7513c85 100644

--- a/kernel/arch/arm/configs/msm8909-1gb_defconfig

+++ b/kernel/arch/arm/configs/msm8909-1gb_defconfig

@@ -614,3 +614,5 @@ CONFIG_MSM_CORE_CTL_HELPER=y

 CONFIG_HAVE_ARCH_SECCOMP_FILTER=y

 CONFIG_SECCOMP=y

 CONFIG_SECCOMP_FILTER=y

+CONFIG_DEBUG_LL=y

+CONFIG_EARLY_PRINTK=y

 34:高通USER关闭QLOAD下载

--- a/kernel/drivers/power/reset/msm-poweroff.c

+++ b/kernel/drivers/power/reset/msm-poweroff.c

@@ -63,7 +63,7 @@ static void *emergency_dload_mode_addr;

 static bool scm_dload_supported;

 static int dload_set(const char *val, struct kernel_param *kp);

-static int download_mode = 1;

+static int download_mode = 0;  //richal changed:disable qdload mode

 module_param_call(download_mode, dload_set, param_get_int,

                        &download_mode, 0644);

 static int panic_prep_restart(struct notifier_block *this,

原文地址:https://www.cnblogs.com/it-tsz/p/13664292.html