应客户需求,在android系统设置中添加一个设置选项,该选项中添加一个开关功能,用于显示和隐藏系统底部导航栏。
首先当然是有系统源码了,RK3288,5.1系统源码一份。
然后就是修改系统设置app,即Settings.apk的源码。
再然后修改系统SystemUI.apk的源码。
最后,通过Settings.apk的开关按钮来触发,发送广播通知给SystemUI.apk来实现导航栏的显示和隐藏逻辑。
环境:
源码放在了公司的服务器上,本猿用的是ubuntu系统。
第一步:连接到服务器上操作
a. 打开终端:Ctrl+shift+T
b. 连接服务器:ssh user_name@ip_address
第二步:进入RK3288源码目录
a. Settings.apk源码路径: RK3288-5.1/packages/apps/Settings
b. SystemUI.apk源码路径: RK3288-5.1/frameworks/base/packages/SystemUI
第三步:修改Settings.apk源码
a.修改RK3288-5.1/packages/apps/Settings/res/xml/dashboard_categories.xml
添加代码:
这几行代码用在点开设置第一个出现在界面中的条目,这里借用的“关于设备”的图标,可见每个条目对应一个fragment。
在包com.android.settings下新建一个类:
package com.android.settings;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.util.Log;
import android.widget.Toast;
import android.content.Context;
import android.content.Intent;
/**
*
* @author TianMing.Xiong
*
*/
public class SetNavigationSettings extends SettingsPreferenceFragment implements Preference.OnPreferenceChangeListener{
private Context mContext;
public static final String HIDE_NAVIGATION_BAR = "android.intent.action.HIDE_NAVIGATION_BAR";
public static final String SHOW_NAVIGATION_BAR = "android.intent.action.SHOW_NAVIGATION_BAR";
@Override
public void onCreate(Bundle icicle) {
// TODO Auto-generated method stub
super.onCreate(icicle);
addPreferencesFromResource(R.xml.navigation_settings);
mContext = getActivity();
// 获取级别描述(组)
Preference set_navigation = getPreferenceManager().findPreference("set_navigation");
CharSequence summary = set_navigation.getSummary();
CharSequence title = set_navigation.getTitle();
Log.e("TAG","summary:"+summary+",title:"+title);
// 监听开关按钮
Preference navigation_is_show_and_hide = getPreferenceManager().findPreference("navigation_is_show_and_hide");
// 用于监听哪个Preference的回调,用key标识
navigation_is_show_and_hide.setOnPreferenceChangeListener(this);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// TODO Auto-generated method stub
String key = preference.getKey();
Log.e("TAG","key:"+key+",value:"+newValue);
if(newValue instanceof Boolean){
Boolean flag = Boolean.valueOf(((Boolean) newValue).booleanValue());
if(flag){
// Toast.makeText(getActivity(), "open", Toast.LENGTH_SHORT).show();
mContext.sendBroadcast(new Intent(HIDE_NAVIGATION_BAR));
}else {
// Toast.makeText(getActivity(), "close", Toast.LENGTH_SHORT).show();
mContext.sendBroadcast(new Intent(SHOW_NAVIGATION_BAR));
}
}
return true;
}
}
此类需要addPreferencesFromResource(R.xml.navigation_settings),在res/xml文件夹下新建navigation_settings.xml
内容:
至此,Settings.apk源码修改完毕!
第四步:修改SystemUI.apk源码
找到包com.android.systemui.statusbar.phone下的PhoneStatusBar.java
添加代码:
import android.content.SharedPreferences;// add by xtm
public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,CircleMenuView.BtnClickCallBack {
/*----------------------------------------------------add by xtm------------------------------------------------------*/
public static final String HIDE_NAVIGATION_BAR = "android.intent.action.HIDE_NAVIGATION_BAR";
public static final String SHOW_NAVIGATION_BAR = "android.intent.action.SHOW_NAVIGATION_BAR";
private static final String NAVIGATION_CONF = "navigation_conf";
private static final String NAVIGATION_KEY = "navigation_key";
private SharedPreferences navigation_sp;
private boolean isShowNavigation = true;
/*----------------------------------------------------------------------------------------------------------*/
在该类的start()方法中的addNavigationBar();这行代码下添加:
addNavigationBar();
/*----------------------------------add by xtm--------------------------------------------------*/
navigation_sp = mContext.getSharedPreferences(NAVIGATION_CONF, Context.MODE_PRIVATE);
isShowNavigation = navigation_sp.getBoolean(NAVIGATION_KEY, true);
if (isShowNavigation) {
displayNavigation();
}else {
hideNavigation();
}
/*------------------------------------------------------------------------------------*/
在本类中代码private BroadcastReceiver winreceiver=new BroadcastReceiver() {....}上方添加:
/*----------------------------------------------------add by xtm------------------------------------------------------*/
private BroadcastReceiver navigationreceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
if(action.equals(SHOW_NAVIGATION_BAR)){
displayNavigation();
navigation_sp.edit().putBoolean(NAVIGATION_KEY,true).apply();
}else if(action.equals(HIDE_NAVIGATION_BAR)) {
hideNavigation();
navigation_sp.edit().putBoolean(NAVIGATION_KEY,false).apply();
}
}
};
public void displayNavigation(){
addNavigationBarInnerLocked();
}
public void hideNavigation(){
removeNavigationBar();
}
private void addNavigationBarInnerLocked(){
if(mNavigationBarView == null){
mNavigationBarView = (NavigationBarView) View.inflate(mContext, R.layout.navigation_bar, null);
mNavigationBarView.setDisabledFlags(mDisabled);
mNavigationBarView.setBar(this);
mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
checkUserAutohide(v, event); return false;
}
});
if (mNavigationBarView == null) return;
prepareNavigationBarView();
try {
mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
} catch (Exception e) {
}
}
}
private void removeNavigationBar() {
if (mNavigationBarView == null) return;
mWindowManager.removeView(mNavigationBarView);
mNavigationBarView = null;
}
/*----------------------------------------------------------------------------------------------------------*/
在函数protected PhoneStatusBarView makeStatusBarView()中添加代码:
/*----------------------------------------------------add by xtm------------------------------------------------------*/
IntentFilter navigationintentfilter=new IntentFilter();
navigationintentfilter.addAction(HIDE_NAVIGATION_BAR);
navigationintentfilter.addAction(SHOW_NAVIGATION_BAR);
context.registerReceiver(navigationreceiver, navigationintentfilter);
/*----------------------------------------------------------------------------------------------------------*/
至此,SystemUI.apk源码修改完毕!
第五步:编译整个系统
连接好服务器的的终端上输入:
1. source build/envsetup.sh
2. lunch
选3 -----(编译java环境)
3. make -----(全部编译)
第六步:找到编译好的apk文件push到设备上,重启看效果:
Settings.apk文件路径:
RK3288-5.1/out/target/product/rk3288/system/priv-app/Settings/
SystemUI.apk文件路径:
RK3288-5.1/out/target/product/rk3288/system/priv-app/SystemUI/
拷贝出来push进设备:
命令:
adb root
adb remount
adb push ~/SystemUI.apk /system/priv-app/SystemUI/
adb push ~/Settings.apk /system/priv-app/Settings/
adb reboot
参考: