Settings.apk 6.0开发记录

其apk在设备上的位置:/system/priv-app/Settings。

开发前准备

  • 除了需要导入Settings的源码,还需导入SettingsLib模块作为依赖
  • 在app目录下新建systemlib目录作为系统库,需添加 如下jar包作为Provider,具体参考模块依赖
    • android_stubs_current_intermediates.jar
    • bouncycastle_intermediates.jar
    • conscrypt_intermediates.jar
    • core-libart_intermediates.jar
    • ext_intermediates.jar
    • framework_intermediates.jar
    • frameworks-core-util-lib_intermediates.jar
    • ims-common_intermediates.jar
    • jsr305_intermediates.jar
    • setup-wizard-lib_intermediates.jar
    • setup-wizard-navbar_intermediates.jar
    • telephony-common_intermediates.jar
  • 整理资源文件,补齐缺失的资源 直到编译通过

一级选项添加流程 以有线网络为例

1.Settings中一级选项的显示是在dashboard_categories.xml中添加的,路径为main\res\xml\,Favorites中有收藏此文件。打开dashboard_categories.xml,选项是按组分类的,如无线和网络、设备、系统,我们自定义的无线网络放在无线和网络组中。先创建EthernetFragment,通过title(Wireless&network)找到无线和网络的dashboard-category。
在上述组里添加如下代码


2.在Settings.java中添加如下代码

 public static class EthernetSettingsActivity extends SettingsActivity {  }

3.在manifest中注册EthernetSettingsActivity

 
        
        
        
        
        
        
        
    //当点击添加的有线网络选项时会跳转到此页面
        
        
    

4.添加有线网络选项的id到SettingsActivity的SETTINGS_FOR_RESTRICTED数组中

private int[] SETTINGS_FOR_RESTRICTED = {
    R.id.wireless_section,//无线
    R.id.wifi_settings,//wifi
    R.id.bluetooth_settings,//蓝牙
    R.id.data_usage_settings,
    R.id.ethernet_settings,//有线网络
    R.id.server_settings,....}

5.将EthernetFragment类名添加到SettingsActivity的ENTRY_FRAGMENTS数组

private static final String[] ENTRY_FRAGMENTS = {
    WirelessSettings.class.getName(),
    EthernetFragment.class.getName(),//有线网络
    ServerSettingFragment.class.getName(),//服务器设置
    OnOffSettingFragment.class.getName(),//开关机设置
    ...}

添加退出选项

退出不需要进入子页面,则不需要注册Activity和添加Fragment。同样打开dashboardcategories.xml,我们把退出选项添加在系统组里,知道title为System的dashboard-category,添加如下代码

 

直接在DashboardTileView的OnClick方法中添加退出点击处理

public void onClick(View v) {
    if (mTile.fragment != null) {
        Utils.startWithFragment(getContext(), mTile.fragment, mTile.fragmentArguments, null, 0,
                mTile.titleRes, mTile.getTitle(getResources()));
    } else if (mTile.intent != null) {
        int numUserHandles = mTile.userHandle.size();
        if (numUserHandles > 1) {
            ProfileSelectDialog.show(((Activity) getContext()).getFragmentManager(), mTile);
        } else if (numUserHandles == 1) {
            getContext().startActivityAsUser(mTile.intent, mTile.userHandle.get(0));
        } else {
            getContext().startActivity(mTile.intent);
        }
    }else if (mTile.id == R.id.exit_settings) {
        //点击退出按钮退出应用
        ((SettingsActivity)getContext()).finish();
    }
}

移除选项,比如位置选项

在SettingsActivity中的updateTilesList()方法里添加如下代码

private void updateTilesList(List target) {
    ....省略一批代码
 // Ids are integers, so downcasting is ok
    int id = (int) category.id;
    int n = category.getTilesCount() - 1;
    while (n >= 0) {
    ....省略一批代码
        else if (id == R.id.location_settings) {
         removeTile=true;
       }
    ....省略一批代码
    n--;
    }

6.0系统默认永不休眠,要显示这个选项,打开app\src\main\res\values\custom_config.xml文件,修改代码如下

 true

系统默认的高亮色比较淡,不容易区分条目是否被选中,打开\src\main\res\values\themes.xml文件,在如下样式中添加自定义背景色


屏幕旋转的处理,显示选项和后台都能控制设备的旋转,前提是Launcher允许桌面旋转(具体操作查看Launcher.apk的修改记录),否则只会应用旋转,桌面不会同步旋转;代码如下,需在子线程中执行:

IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
//保存到全局
Settings.System.putInt(getContentResolver(),Settings.System.USER_ROTATION, value);
//保存到数据库,与后台同步
ShineDataBaseHelper.getInstance(this).save(Common.DESKTOP_ORIENTATION, data);
try {
    wm.freezeRotation(value);
    WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
    wallpaperManager.setBitmap(wallpaperManager.getBitmap());
    Log.d(TAG, "设置旋转完成");
} catch (RemoteException | IOException e) {
    Log.d(TAG, "设置旋转异常");
    e.printStackTrace();
}

提示音和通知选项,在src\main\java\com\android\settings\notification\NotificationSettings.java文件中移除了闹钟和铃音设置,只留下媒体音量,其功能实现在src\main\java\com\android\settings\notification\VolumeSeekBarPreference.java文件中。
主要改动有修改了SeekBarPreference的源码,否则SeekBar控件找不到报空,打开src\main\res\layout\preference_volume_slider.xml,修改id


拷贝SeekBarPreference源码到项目,使VolumeSeekBarPreference继承之,本项目路径为E:\workspace_a64\Settings\app\src\main\java\com\android\settings\shine\SeekBarPreference.java。修改SeekBarPreference的onBindView方法:

@Override
protected void onBindView(View view) {
    super.onBindView(view);
    SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekbar);
//  SeekBar seekBar = (SeekBar) view.findViewById( com.android.internal.R.id.seekbar);
    ...
}

打开VolumeSeekBarPreference.java文件,添加遥控器调节音量的响应,具体修改参考源文件

@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
    if (event.getAction() != KeyEvent.ACTION_UP) {
        if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
                || keyCode == KeyEvent.KEYCODE_EQUALS) {
            mSeekBar.setProgress(mSeekBar.getProgress() + 1);
            mVolumizer.onProgressChanged(mSeekBar,mSeekBar.getProgress(),true);
            return true;
        }
        if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
            mSeekBar.setProgress(mSeekBar.getProgress() - 1);
            mVolumizer.onProgressChanged(mSeekBar,mSeekBar.getProgress(),true);
            return true;
        }
    }
    return false;
}

显示输入法,在系统完成Boot,调用以下方法,在SettingProvider中没有找到默认设置

Settings.Secure.putInt(getContentResolver(), "show_ime_with_hard_keyboard", 1);

修改PhoneWindowManager.java源码,设定对F12按键响应,使遥控器对设置应用的直接调用。找到interceptKeyBeforeDispatching方法添加如下代码:

@Override
public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
...
...
 if (keyCode == KeyEvent.KEYCODE_HOME) {
...响应首页键
...其他按键
}else if(keyCode == KeyEvent.KEYCODE_F12){
    if(down){
        //应用的首页需在清单文件添加类别android.intent.category.SETTINGS
        Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, "android.intent.category.SETTINGS");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
            mContext.startActivityAsUser(intent, UserHandle.CURRENT);
        } catch (ActivityNotFoundException ex) {
           ...
        }
    }
        return -1;   
    }
....

你可能感兴趣的:(Settings.apk 6.0开发记录)