栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android Q - Settings页面添加二级选项

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android Q - Settings页面添加二级选项

简单记录下,本次修改为网络设置中添加一个以太网的选项开关。效果如下:

与Android4.4相差较大,主要修改文件为,在以下路径 packages/apps/Settings 

  • res/values-zh-rCN/strings.xml
  • res/values/config.xml
  • res/xml/network_and_internet_v2.xml
  • src/com/android/settings/network/NetworkDashboardFragment.java
  • src/com/android/settings/network/EthernetPreferenceController.java(新建)
  • src/com/android/settings/utils/ReflectUtil.java(新建)

接下来按照我修改的逻辑进行说明:

1、修改布局文件

路径:res/xml/network_and_internet_v2.xml

说明:其中 order 绝对值越大越靠上,有些我这里未给出的资源可复制其他选项的资源,或者私信或评论我发送你;修改完以下部分你就会发现已经有这个选项了。

    //原本这里是5

...

    
        

...
2、资源文件

路径:res/values-zh-rCN/strings.xml

说明:这里主要是选项标题的一些中文显示,其实我也在 res/values/strings.xml 路径下修改了,但是感觉没啥必要在写一遍。我是直接在最后添加的。

...

    
    以太网
    关闭
    开启
    关闭

路径:res/values/config.xml

说明:配置文件,配置功能开关;由于本次是为了添加以太网的开关选项,因此在此处添加是否显示该选项的开关。

    
    true
 3、实现开关对应的功能

路径:src/com/android/settings/network/NetworkDashboardFragment.java

说明:简单阅读代码可以发现设置页面的功能实现都是由 preference + controller 实现的,而当前文件则是网络页面 controller 的加载或者说实例化(我这么理解应该没错吧~)。

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        
        Bundle args = getArguments();
        if (args != null) {
            if (!args.getBoolean(ARG_SHOW_EXPAND_BUTTON, true)) {
                mChildrenCount = Integer.MAX_VALUE;
            }
        }
        if (FeatureFlagPersistent.isEnabled(context, FeatureFlags.NETWORK_INTERNET_V2)) {
            // UNISOC:Improve the function of turning on and off the Sub
            use(MultiNetworkHeaderController.class).init(getSettingsLifecycle(),
                   getFragmentManager(), mChildrenCount);
        }
        
        use(AirplaneModePreferenceController.class).setFragment(this);
        use(EthernetPreferenceController.class).setFragment(this);    //新加
    }

路径:src/com/android/settings/network/EthernetPreferenceController.java

说明:最终的实现应该都是在 controller 里实现的,由于本次添加的是开关,于是查看了下飞行模式的 controller 并进行了部分修改。开关以太网卡的方式为修改节点,但是搁主线程里看起来非常卡顿,因此使用了线程池,虽然看起来实际开关慢了一点,但不会出现卡顿的现象。这部分代码可直接删除,然后打印 log 即可。

然后说一下这个 preference 的保存方式,修改节点的方法并不能持久保存,在关机或重启之后,会恢复为默认值,所以加了一个开机监听,在开机后将判断条件修改为关。

最后说一下保存数据的方式,说真的,我不太理解,在退出页面后数据就被重置了,不得已改成 SystemProperties 读写数据。方法贴在后面。


package com.android.settings.network;
import android.annotation.SuppressLint;
import com.android.settings.utils.ThreadPool;
import android.content.Context;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.utils.ReflectUtil;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class EthernetPreferenceController extends TogglePreferenceController {
    private static final String TAG = "EthernetPreferenceController";
    private SwitchPreference mEthernetPreference;
    private Fragment mFragment;
    private final MetricsFeatureProvider mMetricsFeatureProvider;
    private Context mContext;
    public EthernetPreferenceController(Context context, String key) {
        super(context, key);
        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
        mContext = context;
    }
    @Override
    public boolean handlePreferenceTreeClick(Preference preference) {
        android.util.Log.d(TAG, "handlePreferenceTreeClick: " + preference.getKey());
        if (TextUtils.equals(preference.getKey(), "usb_ethernet")) {
            changeState(!isChecked());
            return true;
        }
        return false;
    }
    public void setFragment(Fragment hostFragment) {
        mFragment = hostFragment;
    }
    @Override
    @AvailabilityStatus
    public int getAvailabilityStatus() {
        return isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
    }
    public static boolean isAvailable(Context context) {
        return context.getResources().getBoolean(R.bool.config_show_toggle_ethernet)
                && !context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
    }
    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        if (isAvailable()) {
            mEthernetPreference = screen.findPreference(getPreferenceKey());
            android.util.Log.d(TAG, "displayPreference: " + isChecked());
            if (isChecked())
                mEthernetPreference.setSummary(mContext.getString(R.string.settings_eth_open));
            else
                mEthernetPreference.setSummary(mContext.getString(R.string.settings_eth_close));
            mEthernetPreference.setChecked(isChecked());
        }
    }
    @Override
    public boolean setChecked(boolean isChecked) {
        return false;
    }
    public void changeState(boolean state) {
        android.util.Log.d(TAG, "changeState to be = " + state);
        if (state) {
            ReflectUtil.setProperty("persist.flyscale.ethernet", "1");
            mEthernetPreference.setSummary(mContext.getString(R.string.settings_eth_open));
            mEthernetPreference.setChecked(true);
            ThreadPool.getInstance().execute(new Runnable() {
                @Override
                public void run() {
                    write("onnet");
                }
            });
        } else {
            ReflectUtil.setProperty("persist.flyscale.ethernet", "0");
            mEthernetPreference.setSummary(mContext.getString(R.string.settings_eth_close));
            mEthernetPreference.setChecked(false);
            ThreadPool.getInstance().execute(new Runnable() {
                @Override
                public void run() {
                    write("offnet");
                }
            });
        }
        android.util.Log.d(TAG, "changeState: currentState is = " + isChecked());
    }
    @Override
    public boolean isChecked() {
        return TextUtils.equals(ReflectUtil.getProperty("persist.flyscale.ethernet", "0"), "1");
    }

   //mode{onotg,offotg,onnet,offnet}
   private static void write(String mode){
        //这里根据需要自己写实现的功能吧
    }
}
package com.android.settings.utils;
import java.lang.reflect.Method;
public final class ReflectUtil {
    public static String getProperty(String key, String defaultValue) {
        String value = defaultValue;
        try {
            Class c = Class.forName("android.os.SystemProperties");
            Method get = c.getMethod("get", String.class, String.class);
            value = (String)(get.invoke(c, key, defaultValue));
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            return value;
        }
    }
    public static void setProperty(String key, String value) {
        try {
            Class c = Class.forName("android.os.SystemProperties");
            Method set = c.getMethod("set", String.class, String.class);
            set.invoke(c, key, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

总之,抛开我不太理解的地方,还是相对容易的。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/862335.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号