Android14 Settings应用添加有线网开关条目实现

Android14 Settings应用添加有线网开关条目

文章目录

  • Android14 Settings应用添加有线网开关条目
    • 一、前言
    • 二、适配修改
      • 1、network_provider_settings.xml
      • 2、NetworkProviderSettings.java
      • 3、TurnOnOffEthernetNetworkController.java
      • 4、去除有线网提示条目。
      • 5、效果UI
        • (1)修改前效果
        • (2)修改后效果
    • 三、其他
      • 1、Android Settings应用添加有线网开关条目小结
        • (1)主要修改适配的代码:
      • 2、关于不同Android系统版本原生Settings Wifi条目的获取代码
      • 4、Android13 有线网开关研究
      • 5、Android AccessPoint 已连接的wifi信息未显示处理

一、前言

背景:
Android 原生Settings应用没有有线网开关条目;
Tv平台一般是有有线网连接的,如果没有有线网控制条目是不太方便的;

如果要在原生Settings添加有线网开关和显示有线网ip,要如何实现呢?

目前主要的商显TV中,只有我开发的方案中有些原生设置Settings 在某些方案上有修改了原生Settings的添加有线网开关控制,视源、朗国、创维、三星那些都是没修改的。

本文简单实现一下,有需要的可以参考修改。

二、适配修改

1、network_provider_settings.xml

在布局文件添加一个有线网开关UI条目控制;

这个布局文件是点击二级菜单"互联网"显示的界面主要包含条目内容:
有线网提示(接入有线网才有),飞行模式提示(开启飞行模式才有),
Wifi开关、Wifi列表、添加网络按键,网络偏好设置,已保存的网络。

Settings\res\xml\network_provider_settings.xml

    //原本有的有线网提示<Preferenceandroid:key="connected_ethernet_network"android:title="@string/ethernet"android:summary="@string/to_switch_networks_disconnect_ethernet"android:icon="@drawable/ic_settings_ethernet"/>//新增的有线网开关条目
+    <SwitchPreference
+        android:key="ethernet_turn_off"
+        android:title="@string/ethernet" />//飞行模式提示<PreferenceCategoryandroid:key="provider_model_mobile_network"android:title="@string/summary_placeholder"android:layout="@layout/preference_category_no_label"settings:isPreferenceVisible="@bool/config_show_sim_info"settings:controller="com.android.settings.network.NetworkMobileProviderController"/>//Wifi开关<com.android.settingslib.RestrictedSwitchPreferenceandroid:key="main_toggle_wifi"android:title="@string/wifi"settings:keywords="@string/keywords_wifi"settings:allowDividerAbove="true"/>//已连接的Wifi ?<PreferenceCategoryandroid:key="connected_access_point"android:layout="@layout/preference_category_no_label"/>//保持状态的Wifi列表 ?<PreferenceCategoryandroid:key="first_access_points"android:layout="@layout/preference_category_no_label"/>//剩余的扫描到的的Wifi列表 ?<PreferenceCategoryandroid:key="access_points"android:layout="@layout/preference_category_no_label"/>//网络偏好设置<Preferenceandroid:key="configure_network_settings"android:title="@string/network_and_internet_preferences_title"settings:allowDividerAbove="true"android:fragment="com.android.settings.wifi.ConfigureWifiSettings"/>//已保存的网络<Preferenceandroid:key="saved_networks"android:title="@string/wifi_saved_access_points_label"android:fragment="com.android.settings.wifi.savedaccesspoints2.SavedAccessPointsWifiSettings2"/>

res/value 的资源文件:

//英文<string name="to_switch_networks_disconnect_ethernet">To switch networks, disconnect ethernet</string>
//中文<string name="to_switch_networks_disconnect_ethernet" msgid="6615374552827587197">"如要切换网络,请拔出以太网网线"</string>

Android 原生应用没有有线网开关控制,有线网连接后,
如果正常获取到有线网ip,是有线使用有线网的,无法正常连接Wifi网络,
所以会友情提示"如要切换网络,请拔出有线网".

2、NetworkProviderSettings.java

Wifi开关和Wifi列表显示都在这个类。

import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;/*** UI for Mobile network and Wi-Fi network settings.*/
@SearchIndexable
public class NetworkProviderSettings extends RestrictedSettingsFragment ...{ConnectedEthernetNetworkController mConnectedEthernetNetworkController;+    TurnOnOffEthernetNetworkController mTurnOnOffEthernetNetworkController;private void addPreferences() {
...addConnectedEthernetNetworkController();
+        addTurnOnOffEthernetNetworkController();}//add by liwenzhi  ++++ 下面这个方法是添加的//主要就是开关监听,调用方法private void addTurnOnOffEthernetNetworkController() {if (mTurnOnOffEthernetNetworkController == null) {mTurnOnOffEthernetNetworkController =new TurnOnOffEthernetNetworkController(getContext(), TurnOnOffEthernetNetworkController.KEY);}SwitchPreference  switchPreference = (SwitchPreference) findPreference("ethernet_turn_off");mTurnOnOffEthernetNetworkController.updateState(switchPreference);switchPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {@Overridepublic boolean onPreferenceChange(Preference preference, Object newValue) {boolean isCheck = (boolean) newValue;Log.i(TAG, "onPreferenceChange preference = " + preference + ", isCheck = " + isCheck);mTurnOnOffEthernetNetworkController.onPreferenceChange(preference, newValue);return true;}});}public void onStart() {super.onStart();
+        mTurnOnOffEthernetNetworkController.onStart(); //主要用来广播监听 + 更新有线网ip}@Overridepublic void onStop() {
+        mTurnOnOffEthernetNetworkController.onStop(); //停止广播监听}}

3、TurnOnOffEthernetNetworkController.java

package com.android.settings.network;import static com.android.settings.network.InternetUpdater.INTERNET_ETHERNET;import android.content.Context;
import android.util.Log;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.EthernetManager;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkInfo;
import android.os.Handler;
import android.provider.Settings;
import android.text.TextUtils;import androidx.preference.Preference;
import androidx.preference.SwitchPreference;import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;/*** PreferenceController to show the connected ethernet network turn on /off.* 自定义添加的有线网开关*/
public class TurnOnOffEthernetNetworkController extends BasePreferenceController implementsPreference.OnPreferenceChangeListener {private static final String TAG = "TurnOnOffEthernetNetworkController";private static final String NET_CHANGE_ACTION = ConnectivityManager.CONNECTIVITY_ACTION; //所有网络变化广播private static final String ETHERNET_STATE_CHANGE = "action.ebsw.eth.status.change"; //底层自定义有线网络插拔广播(并非共用的,是底层自己开发的)public static final String KEY = "ethernet_turn_off";private Context mContext;private Preference mPreference;private SettingsValueChangeContentObserver mContentOb; //监听 Settings ethernet_onpublic TurnOnOffEthernetNetworkController(Context context, String preferenceKey) {super(context, preferenceKey);Log.i(TAG, "TurnOnOffEthernetNetworkController preferenceKey  = " + preferenceKey);mContext = context;//注册监听Settings.Global.ETHERNET_ON 属性变化mContentOb = new SettingsValueChangeContentObserver();context.getContentResolver().registerContentObserver(Settings.System.getUriFor("ethernet_on"), true, mContentOb);//注册监听}@Overridepublic String getPreferenceKey() {return KEY;}@Overridepublic int getAvailabilityStatus() {return AVAILABLE;}//自定义的,非原生public void updateState(Preference preference) {Log.i(TAG, "updateState preference = " + preference);final boolean settingsOn = isEthernetEnabled(mContext);Log.i(TAG, "updateState settingsOn = " + settingsOn);((SwitchPreference) preference).setChecked(settingsOn);mPreference = preference;//mPreference.setSummary("on/off:" + settingsOn); //testupdateEthernetIp();}//自定义的,非原生public boolean onPreferenceChange(Preference preference, Object newValue) {final boolean settingsOn = (Boolean) newValue;Log.i(TAG, "onPreferenceChange settingsOn = " + settingsOn);return enableEthernet(mContext, settingsOn);}public boolean enableEthernet(Context context, boolean enabled) {Log.i(TAG, "enableEthernet enabled = " + enabled);EthernetManager ethernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);ethernetManager.setEthernetEnabled(enabled);Settings.Global.putInt(context.getContentResolver(),"ethernet_on", enabled? EthernetManager.ETHERNET_STATE_ENABLED:EthernetManager.ETHERNET_STATE_DISABLED);return true;}public boolean isEthernetEnabled(Context context) {Log.i(TAG, "isEthernetEnabled.");int ethernetSate = 0;final ContentResolver cr = context.getContentResolver();try {ethernetSate = Settings.Global.getInt(cr, "ethernet_on", EthernetManager.ETHERNET_STATE_ENABLED);} catch (Exception e) {ethernetSate = EthernetManager.ETHERNET_STATE_DISABLED;}return ethernetSate == EthernetManager.ETHERNET_STATE_ENABLED;}

注意 :Settings.Global.ETHERNET_ON 属性在 Android8之后的版本好像就没有了;
如果需要全局定义可以自己在Settings.java源码中添加定义;
其实也可以不用定义,直接使用 "etherent_on"字符串就行;也是一样能监听变化能记忆能使用;

也可以使用prop属性记录有线网开关状态,不过不方便监听状态变化。

4、去除有线网提示条目。

Settings\src\com\android\settings\network\ConnectedEthernetNetworkController.java

    @Overridepublic boolean isAvailable() {
-        return mInternetType == INTERNET_ETHERNET;
+        //not to show this item ,change by liwenzhi
+        return false;}

代码修改可以动态设置显示或者隐藏,通过某些状态或者prop属性;
如果不想改Java代码,应该是可以在xml文件中直接去除 key=“connected_ethernet_network” 条目那项。

5、效果UI

(1)修改前效果

未接入有线网的情况的显示:
在这里插入图片描述
这个是最普通的正常情况的显示。

接入有线网的情况下的显示:
在这里插入图片描述

可以看到这里就提示了让你拔掉有线网,是不是比较low。

默认情况,wifi和有线网连接是不兼容的,有线网优先级高于wifi,
所以优先连接的是有线网;如果拔出有线网,是会自动连接wifi的;
如果有需求也是可以修改系统源码,设置有线网和wifi共存,同时连接的。

(2)修改后效果

有线网开关开启并且接入有线网:
在这里插入图片描述
这里查看简单明了的,显示了有线网开关和有线网ip地址。

有线网开关关闭:
在这里插入图片描述
这里可以看到有线网关闭后,Wif是可以连接的;
如果打开有线网开关,但是未接入有线网插头,也是能连接wifi的,只是有线网那里并不显示ip地址。

三、其他

1、Android Settings应用添加有线网开关条目小结

(1)主要修改适配的代码:
network_provider_settings.xml //有线网开关条目的添加
NetworkProviderSettings.java //有线网开关条目的关联
TurnOnOffEthernetNetworkController.java //+自定义的有线网控制显示类
ConnectedEthernetNetworkController.java //有线网默认提示是否显示

这里是添加有线网开关设置在三级目录里面,
也可以添加在二级目录里面,和Wifi、飞行模式、热点共享同级目录下;

2、关于不同Android系统版本原生Settings Wifi条目的获取代码

查看了Wifi列表获取的代码是有较大差异的:

Android9 或者更低的版本使用的是:
List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();Android11 或者更新的版本获取Wifi使用的是:
List<WifiEntry> wifiEntries = mWifiPickerTracker.getWifiEntries();因为 AccessPoint 过时了,所以使用的是 WifiEntry;
AccessPoint 是系统SettingsLib包封装的对象,WifiEntry 是系统framework包的对象;

使用 WifiEntry 对象似乎是为了更容易适配Settings应用的 Preference 布局控件。

无论是AccessPoint还是WifiEntry,都是有暴露 getWifiConfiguration()方法获取都某个Wifi的配置信息WifiConfiguration对象。

我这里自定义开发的设置应用从Android7开始一直是使用 AccessPoint 那套显示和连接Wifi,没啥大问题;
也有一个方案出现过列表不显示某个已连接的隐藏Wifi的情况,直接修改的SettingsLib源码解决的。

4、Android13 有线网开关研究

Android13 的api 提供了有线网开关 EthernetManager.setEthernetEnabled(boolean),
Android9 如果要设置有线网开关,需要自己实现。

https://blog.csdn.net/wenzhi20102321/article/details/131871354

5、Android AccessPoint 已连接的wifi信息未显示处理

一个wifi列表未显示已连接的wifi信息问题记录。
本文最后又原生Settings 的Wifi列表界面显示分析,有兴趣的可以看看。

https://blog.csdn.net/wenzhi20102321/article/details/146536423

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/41729.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序如何接入直播功能

一、小程序直播开通背景 1.政府资质要求 政府的要求&#xff0c;小程序开通直播需要注册主体具备互联网直播的资质&#xff0c;普通企业需要《信息网络传播视听节目许可证》&#xff0c;表演性质的直播需要《网络文化经营许可证》&#xff0c;政府主体需要《社会信用代码》及…

【Linux】MAC帧

目录 一、MAC帧 &#xff08;一&#xff09;IP地址和MAC地址 &#xff08;二&#xff09;MAC帧格式 &#xff08;三&#xff09;MTU对IP协议的影响、 &#xff08;四&#xff09;MTU对UDP协议的影响 &#xff08;五&#xff09;MTU对TCP协议的影响 二、以太网协议 &…

如何查看window电脑的GPU信息

GPU&#xff08;图形处理器&#xff0c;Graphics Processing Unit&#xff09;和显卡是两个密切相关但不同的概念 概念 1. ‌基本概念‌ ‌GPU‌&#xff1a;是专门用于处理图像和视频信息的微处理器&#xff0c;拥有强大的并行计算能力&#xff0c;主要负责图形渲染、数值分…

大数据判存算法

所谓的大数据判存算法&#xff0c;就是如何在海量数据中快速判断某个数据是否存在。这里用到的知识是布隆过滤器&#xff08;Bloom Filter&#xff09;&#xff0c;下面按照 what - why - how 的顺序来学习它。 1、什么是布隆过滤器 布隆过滤器&#xff08;英语&#xff1a;B…

Solr-搜索引擎-入门到精通

以下是对 Apache Solr 的简介及其常用语法的快速入门指南&#xff1a; 一、Solr 是什么&#xff1f; • 核心定位&#xff1a;Apache Solr 是一个基于 Lucene 的高性能、开源的搜索平台&#xff0c;支持全文检索、分词、高亮、聚合统计等功能。 • 核心功能&#xff1a; • 全…

Ajax与Axios,以及Apifox的入门使用

Ajax与Axios&#xff0c;以及Apifox的入门使用 作者&#xff1a;blue 时间&#xff1a;2025.3.20 文章目录 Ajax与Axios&#xff0c;以及Apifox的入门使用1.Ajax2.Axios3.Apifox的基本使用内容Path 参数定义语法用途 Query 参数定义语法用途 1.Ajax 概念&#xff1a;Asynchr…

Spring MVC拦截器

一、什么是拦截器 拦截器是 SpringMVC 提供的一种可以在请求处理过程中对请求进行预处理或后处理的机制。简单来说&#xff0c;拦截器就像是一位“守门员”&#xff0c;它拦住所有进来的请求&#xff0c;根据设定的规则决定是否放行或者进行某些操作。 拦截器可以&#xff1a…

mysql语句 聚合+分组+内外链接

1.聚合函数 1.count 记数 2.sum 求和 3.avg *语法&#xff1a;select avg&#xff08;列名&#xff09; from 表名&#xff1b; 4.max 求最大值 5.min 求最小值 求一个班级数学平均分&#xff1f; select avg&#xff08;ifnull&#xff08;math&#xff0c;0&#x…

WPF 与 C# 融合开发:从基础到高级应用(一)

WPF 与 C# 融合开发&#xff1a;从基础到高级应用 一、C# 语言基础回顾 1.1 C# 语言概述 C# 是微软开发的一种现代、面向对象的编程语言&#xff0c;它融合了 C、C 和 Java 等语言的优点&#xff0c;具有简洁、安全、高效等特点。C# 广泛应用于 Windows 平台的应用开发&…

【Linux】IP协议

目录 一、IP协议的概念 二、IP协议的报头 &#xff08;一&#xff09;IP协议报文的封装、解包和分用 &#xff08;二&#xff09;8位生存时间 &#xff08;三&#xff09;IP分片 三、IP协议的网段划分 &#xff08;一&#xff09;为什么需要网段划分 &#xff08;二&am…

如何快速下载并安装 Postman?

从下载、安装、启动 Postman 这三个方面为大家详细讲解下载安装 Postman 每一步操作&#xff0c;帮助初学者快速上手。 Postman 下载及安装教程(2025最新)

计算机网络高频(三)UDP基础

计算机网络高频(三)UDP基础 1.UDP的头部格式是什么样的?⭐ UDP 头部具有以下字段: 源端口(Source Port):16 位字段,表示发送方的端口号。目标端口(Destination Port):16 位字段,表示接收方的端口号。长度(Length):16 位字段,表示 UDP 数据报(包括头部和数据部…

2024年MathorCup数学建模B题甲骨文智能识别中原始拓片单字自动分割与识别研究解题全过程文档加程序

2024年第十四届MathorCup高校数学建模挑战赛 B题 甲骨文智能识别中原始拓片单字自动分割与识别研究 原题再现&#xff1a; 甲骨文是我国目前已知的最早成熟的文字系统&#xff0c;它是一种刻在龟甲或兽骨上的古老文字。甲骨文具有极其重要的研究价值&#xff0c;不仅对中国文…

【深度学习的数学】导数

导数的定义。好像是从极限开始的。比如说&#xff0c;函数f(x)在点xa处的导数&#xff0c;就是当h趋近于0时&#xff0c;[f(ah) - f(a)]除以h的极限&#xff0c;对吧&#xff1f;公式应该是这样的&#xff1a;f’(a) lim_{h→0} [f(ah) - f(a)] / h。这个极限如果存在的话&…

word文件转换为Markdown格式

目录 一、前言1.1、poi-ooxml、docx4j、aspose-words对比二、poi-ooxml技术实现一、前言 顺应时代技术的变更及高效协同理念的影响,非结构化信息展示、存储、应用等也由传统文档向在线协同文档的演变,类似腾讯在线文档。   目前大多数在线文档支持的是Markdown格式,因此这…

【Hugging Face 开源库】Diffusers 库 —— 扩散模型

Diffusers 的三个主要组件1. DiffusionPipeline&#xff1a;端到端推理工具__call__ 函数callback_on_step_end 管道回调函数 2. 预训练模型架构和模块UNetVAE&#xff08;Variational AutoEncoder&#xff09;图像尺寸与 UNet 和 VAE 的关系EMA&#xff08;Exponential Moving…

langserve搭建方法

文章目录 安装 langserver安装 langchain-cli创建langserve脚手架使用poetry管理包 安装 langserver pip install langserve安装 langchain-cli pip install langchain-cli创建langserve脚手架 langchain app new 项目名后续交互界面全回车&#xff0c;接着cd到 项目名 目录…

网络基础-路由器和交换机工作配置

三、路由器和交换机的工作原理配置以及华为体系下的小型网络的搭建 3.1路由基础 3.1.1数据转发 通过链路层交换机和网络层路由器进行数据转发 交换机&#xff08;链路层&#xff09;mac地址表的数据转发路由器&#xff08;网络层&#xff09; ip路由表的数据转发 隔离广播域…

mysql高级,mysql体系结构,mysql引擎,存储过程,索引,锁

1.mysql体系结构 1&#xff09; 连接层 主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念&#xff0c;为通过认证安全接入的客户端提供线程。同样在该层上可以实现基于SSL的安全链接。服务器也会为安全接入的每个客户端验证它所具有的操作…

Unity高清渲染管线

Unity高清渲染管线——1 unity高清渲染管线是渲染管线的一种&#xff0c;在看完《创造高清3D虚拟世界》这本书的前两章以及第三张第二小节后终于对unity的高清渲染管线也是有了一个初步的认知&#xff0c;以下是我个人理解仅作参考&#xff1a; unity高清渲染管线项目模板比起…