美文网首页
Settings.apk 6.0开发记录

Settings.apk 6.0开发记录

作者: 风骚无俩 | 来源:发表于2017-04-01 17:47 被阅读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。
在上述组里添加如下代码

<dashboard-tile
 //此id要添加到SettingsActivity的SETTINGS_FOR_RESTRICTED数组中,如果id不存在此数组,加载时会移除
android:id="@+id/ethernet_settings"
android:title="有线网络" 
//此Fragment为之前创建的路径,名称要添加到SettingsActivity的ENTRY_FRAGMENTS数组中
android:fragment="com.android.settings.shine.EthernetFragment"
android:icon="@drawable/ic_settings_data_usage"/>

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

 public static class EthernetSettingsActivity extends SettingsActivity {  }

3.在manifest中注册EthernetSettingsActivity

 <activity
    android:name=".Settings$EthernetSettingsActivity"
    android:configChanges="orientation|keyboardHidden|screenSize"
    android:label="有线网络设置"
    android:taskAffinity="">
        <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <action android:name="android.settings.ETHERNET_SETTINGS"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.VOICE_LAUNCH"/>
        <category android:name="com.android.settings.SHORTCUT"/>
        </intent-filter>
    //当点击添加的有线网络选项时会跳转到此页面
        <meta-data
            android:name="com.android.settings.FRAGMENT_CLASS"
            //真正显示的内容,路径与dashboard_categories.xml中注册的一样
            android:value="com.android.settings.shine.EthernetFragment"/>
        <meta-data
    android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
    //id与dashboard_categories.xml中注册的一样
    android:resource="@id/ethernet_settings"/>
    </activity>

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,添加如下代码

 <dashboard-tile
    //此id可作为身份判断
    android:id="@+id/exit_settings"
    android:title="退出"
    android:icon="@drawable/ic_settings_about"
    />

直接在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<DashboardCategory> 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文件,修改代码如下

 <bool name="config_show_screen_off_never_timeout" translatable="false">true</bool>

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

<style name="Theme.Settings" parent="Theme.SettingsBase">
...省略其他样式设置
//修改高亮色
<item name="android:colorControlHighlight">@color/memory_user_light</item>
</style>

屏幕旋转的处理,显示选项和后台都能控制设备的旋转,前提是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

<SeekBar 
    //@*android:id/seekbar 源代码
    android:id="@+id/seekbar"
    android:layout_marginStart="24dp"
    android:layout_gravity="center_vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

拷贝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开发记录

      本文链接:https://www.haomeiwen.com/subject/rptwottx.html