首页 > 代码库 > Android源码问题解答之三(状态栏和锁屏)

Android源码问题解答之三(状态栏和锁屏)

case1:如何调整状态栏中通知栏里图标的间隔

状态栏中通知栏的图标大多不是方方正正的矩形或者正方形,但是一旦两个或者两个以上的方正的图标相邻时,没有间隙,会有视觉上的局促感。
可以通过给图标增加间隙的方法,来使其更加美观。修改如下:
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

        for (int i=0; i<toShow.size(); i++) {
            View v = toShow.get(i);            
            if (v.getParent() == null) {
+               v.setPadding(2, 0, 2, 0);
                mNotificationIcons.addView(v, i, params);
            }
        }

setPadding(int left,int top,int right,int bottom)的四个参数值可以根据实际情况进行赋值。
case2:如何修改锁屏提示音的默认值

在frameworks/base/packages/SettingsProvider/res/values/defaults.xml文件中,修改以下值就可以默认打开或关闭锁屏的提示音:

<integer name="def_lockscreen_sounds_enabled">1</integer>

1为开启,0为关闭

case3:如何调整状态栏收缩展开速度?

调整状态栏收缩展开速度:

请在\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\PanelView.java

添加:

    public static final float FLING_MIN_VELOCITY = 2000;//设定fling最小速度

在函数animationTick中增加以下粗体代码:

    private void animationTick(long dtms) {
        if (!mTimeAnimator.isStarted()) {       

            ......
            if (mRubberbanding) {
                mClosing = true;
            } else if (mVel == 0) {
                // if the panel is less than halfway open, close it
                mClosing = (mFinalTouchY / getFullHeight()) < 0.5f;
            } else {
                mClosing = mExpandedHeight > 0 && mVel < 0;
            }

            //add

            if(mVel > 0 && mVel <FLING_MIN_VELOCITY){
                mVel = FLING_MIN_VELOCITY;
            }else if(mVel < 0 && mVel > -FLING_MIN_VELOCITY){
                mVel = -FLING_MIN_VELOCITY;
            }
        } else if (dtms > 0) {

        ......

        }

其中:FLING_MIN_VELOCITY这个值代表最小的速度,可以根据实际情况及需求进行调整,值越大,速度越快。

case4:如何让一个activity 浮在锁屏界面的上方,按返回后再进入解锁界面

可以给当前activity加上FLAG_SHOW_WHEN_LOCKED的属性,如下:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);

加上这个属性后,该activity就可以 浮在锁屏界面的上方,需要按返回后再进入解锁界面。

case5:如何去掉开机动画结束后的上锁声音?

默认情况下手机开机后的上锁声音是关闭的,并且即便开启的话,由于在开机音乐的播放下,也是听不到上锁声音的。但是如果去掉了开机音乐,开启了初次上锁声音,就会听到该声音,影响用户体验,修改如下:
将frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
    // Whether the next call to playSounds() should be skipped.  Defaults to
    // true because the first lock (on boot) should be silent.
    private boolean mSuppressNextLockSound = true;
修改为:
private boolean mSuppressNextLockSound = false;
case6:如何在应用中默认全屏,隐藏状态栏和标题栏

在应用程序中,如何默认全屏,隐藏状态栏和标题栏。
修改如下:
在Activity的onCreate()方法中加入:
requestWindowFeature(Window.FEATURE_NO_TITLE);//设置界面无标题
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏显示
或者在AndroidManifest.xml中添加样式
隐藏标题栏需要使用预定义样式:android:theme=”@android:style/Theme.NoTitleBar”.
隐藏状态栏:android:theme=”@android:style/Theme.NoTitleBar.Fullscreen”.

case7:如何屏蔽掉屏幕处于激活状态时点击power键屏幕熄灭的功能?

修改power键消息的传递,参见:


public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
   ......
   case KeyEvent.KEYCODE_POWER: {
   
    if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {
-        result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP;
     }
  }
}

将上面那句注释掉就可以了,不会影响到power键的关机等功能。

case8:如何在activity中禁止状态栏下拉?

禁止下拉栏下拉,可以参考如下方法,


在相关activity的onCreate,onResume,onStop接口中添加相应逻辑即可。具体如下:

import android.app.StatusBarManager;
import android.content.Context;

private StatusBarManager sStatusBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (sStatusBar == null) {
            sStatusBar = (StatusBarManager)getSystemService(Context.STATUS_BAR_SERVICE);
        }   
    }

    @Override
    public void onResume() {
        super.onResume();
        if (sStatusBar != null) {
            sStatusBar.disable(StatusBarManager.DISABLE_EXPAND);
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (sStatusBar != null) {
            sStatusBar.disable(StatusBarManager.DISABLE_NONE);
        }
     }

case9:如何让下拉栏情景模式切换按钮增加切换到户外模式的功能?

定位到frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\QuickSettingsModel.java中,按照如下红色代码修改即可:


第一步:设置可在各个情景模式之间切换,在addVolumeTile的onClick方法中添加下面红色代码:

                if (AudioManager.RINGER_MODE_SILENT == ringerMode) {
                    ...
                } else if (AudioManager.RINGER_MODE_VIBRATE == ringerMode) {
                    Settings.System.putInt(mResolver,
                            Settings.System.SOUND_EFFECTS_ENABLED, 1);
                    mAudioManager.setRingerMode(AudioManager.RINGER_MODE_OUTDOOR);
                } else if (AudioManager.RINGER_MODE_OUTDOOR == ringerMode) {
                    Settings.System.putInt(mResolver,
                            Settings.System.SOUND_EFFECTS_ENABLED, 1);
                    mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
                } else {
                    ...
                }


第二步:设置切换到户外模式时,需要显示的图片。由于平台版本默认无此功能,因此需要自行添加一张图片到systemui的资源中。然后按照下面方式修改,在onVolumeStateChanged方法中添加下面红色代码:

        if (AudioManager.RINGER_MODE_VIBRATE == ringerMode) {
            mVolumeTileState.iconId = R.drawable.ic_qs_vibrate_on_sprd;
        } else if (AudioManager.RINGER_MODE_SILENT == ringerMode) {
            mVolumeTileState.iconId = R.drawable.ic_qs_silent_on_sprd;
        } else if (AudioManager.RINGER_MODE_OUTDOOR == ringerMode) {
            mVolumeTileState.iconId = R.drawable.ic_qs_gps_on_sprd; //这里为新增的图片
        } else {
            mVolumeTileState.iconId = R.drawable.ic_qs_general_on_sprd;
        }

case10:如何修改锁屏界面显示的日期字体大小
在hvga版本中由于屏幕有限,在锁屏界面有时需要改小显示日期字体的大小,这样才能在锁屏界面中容纳更多的东西。在其他版本中有时为了布局的美观也会将字体改大或者改小。
需要修改文件frameworks/base/packages/Keyguard/res/values/dimens.xml中widget_label_font_size对应的值。
例如:
修改前:
<dimen name="widget_label_font_size">16dp</dimen>
修改后:
<dimen name="widget_label_font_size">14dp</dimen>

原因:
锁屏界面的显示时间对应的view是文件frameworks/base/packages/Keyguard/res/layout/keyguard_status_area.xml中的
<TextClock android:id="@+id/date_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/clock_white"
    style="@style/widget_label"
    android:gravity="center"
    />
而widget_label的定义在文件frameworks/base/packages/Keyguard/res/values/styles.xml中为
<style name="widget_label">
    <item name="android:textAllCaps">true</item>
    <item name="android:textSize">@dimen/widget_label_font_size</item>
</style>
而widget_label_font_size的定义在文件frameworks/base/packages/Keyguard/res/values/dimens.xml中。

case11:如何修改锁屏界面显示的时间字体大小
在hvga版本中由于屏幕有限,在锁屏界面有时需要改小显示时间字体的大小,这样才能在锁屏界面中容纳更多的东西。在其他版本中有时为了布局的美观也会将字体改大或者改小。
需要修改文件frameworks/base/packages/Keyguard/res/values/dimens.xml中widget_big_font_size对应的值。
例如:
修改前:
<dimen name="widget_big_font_size">80dp</dimen>
修改后:

<dimen name="widget_big_font_size">48dp</dimen>

原因:
锁屏界面的显示时间对应的view是文件frameworks/base/packages/Keyguard/res/layout/keyguard_status_view.xml中的
<TextClock
    android:id="@+id/clock_view"
    ...
    style="@style/widget_big_thin"
    .../>
而widget_big_thin的定义在文件frameworks/base/packages/Keyguard/res/values/styles.xml中为
<style name="widget_big_thin" parent="big_thin">
    <item name="android:textSize">@dimen/widget_big_font_size</item>
</style>
而widget_big_font_size的定义在文件frameworks/base/packages/Keyguard/res/values/dimens.xml中。

case12:如何修改锁屏界面显示的机主信息和充电信息字体大小
在hvga版本中由于屏幕有限,在锁屏界面有时需要改小机主信息和充电信息字体大小,这样才能在锁屏界面中容纳更多的东西。在其他版本中有时为了布局的美观也会将字体改大或者改小。
需要修改文件frameworks/base/packages/Keyguard/res/values/dimens.xml中kg_status_line_font_size对应的值。
例如:
修改前:
<dimen name="kg_status_line_font_size">20dp</dimen>
修改后:
<dimen name="kg_status_line_font_size">12dp</dimen>

case13:如何修改锁屏界面密码框字体的大小
有时为了布局的美观会将锁屏界面密码框字体改大或者改小,
需要修改文件frameworks/base/packages/Keyguard/res/layout/keyguard_password_view.xml文件中
<EditText android:id="@+id/passwordEntry" />对应的android:textSize属性的值

例如:
修改前:
<EditText android:id="@+id/passwordEntry"
    ...
    android:textSize="26sp"
    ...
    />
修改后:
<EditText android:id="@+id/passwordEntry"
    ...
    android:textSize="22sp"
    ...
    />

case14:如何让锁屏界面日期字符串与设置模块设置的日期显示格式字符串完全相同?

需要修改两个文件即可:


1.定位到\frameworks\base\packages\Keyguard\src\com\android\keyguard\KeyguardStatusView.java的refresh函数:

修改前:

final String dateFormat = DateFormat.getBestDateTimePattern(locale,
                res.getString(R.string.abbrev_wday_month_day_no_year));

修改后:

final String dateFormat = "KeyguardDateSameForSetting";


2.定位到\frameworks\base\core\java\android\widget\TextClock.java的onTimeChanged函数:

修改前:

setText(DateFormat.format(mFormat, mTime));


修改后:

        if (mFormat.equals("KeyguardDateSameForSetting")) {
            setText(DateFormat.getDateFormat(getContext()).format(mTime.getTime()));
        } else {
            setText(DateFormat.format(mFormat, mTime));
        }

case15:设置模块中切换情景模式为户外模式后,如何让状态栏上显示户外模式图标?

版本中是默认不支持状态栏显示户外模式图标的,如果需要显示,需要在systemui模块新增相关图标和字符串。


定位到frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\PhoneStatusBarPolicy.java的updateVolume方法中,增加如下红色代码即可

        final boolean visible = ringerMode == AudioManager.RINGER_MODE_SILENT ||
                ringerMode == AudioManager.RINGER_MODE_OUTDOOR ||
                ringerMode == AudioManager.RINGER_MODE_VIBRATE;

       if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {

            ...

        } else if (ringerMode == AudioManager.RINGER_MODE_OUTDOOR) {
            iconId = R.drawable.stat_sys_outdoor; //新增图片id
            contentDescription = mContext.getString(R.string.stat_sys_outdoor); //新增字符串id
        } else {

            ...

        }

case16:解锁界面触摸锁图标或滑动到某一功能上会有震动反馈,其强度如何调整
android\frameworks\base\packages\Keyguard\res\layout  keyguard_glow_pad_view.xml

修改如下震动时长即可,0是不震动,数值越大震动感越强

-    prvandroid:vibrationDuration="20"
+    prvandroid:vibrationDuration="40"


Android源码问题解答之三(状态栏和锁屏)