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.mzph.cn/news/899113.shtml

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

相关文章

Axure RP设计软件中的各种函数:包括数字、数学、字符串、时间及中继器函数,详细解释了各函数的用途、参数及其应用场景。

文章目录 引言函数分类数字函数数学函数字符串函数时间函数函数中继器函数引言 在axure交互设计时,函数可以用在条件公式和需要赋值的地方,其基本语法是用双方括号包含,变量值和函数用英文句号连接。 在交互事件编辑器中通过fx按钮插入函数表达式,例如设置文本内容为: …

c#难点整理3

1.静态类的说明 a.静态类里不能定义实例方法&#xff0c;实例属性&#xff0c;所以说非静态类是无法继承静态类的。父类无法拥有实例化的方法和属性&#xff0c;子类可以&#xff0c;这从逻辑上是矛盾的&#xff0c;不符合继承的逻辑。 b.那么静态类与静态类之间能否继承能呢…

AIP-191 文件和目录结构

编号191原文链接https://google.aip.dev/191状态批准创建日期2019-07-25更新日期2019-07-25 统一的文件和目录结构&#xff0c;虽然在技术上差别不大&#xff0c;但可以让用户和审查者更容易阅读API界面定义。 指南 注意 以下指南适合于使用protobuf定义的API&#xff0c;例如…

Win11+VS2022+CGAL5.6配置

1. CGAL库简介 CGAL&#xff08;Computational Geometry Algorithms Library&#xff09;是一个开源的计算几何算法库&#xff0c;主要用于处理几何问题和相关算法的实现。它提供了丰富的几何数据结构和高效算法&#xff0c;覆盖点、线、多边形、曲面等基本几何对象的表示与操…

手搓全自动文章多平台发布系统:5、跨页面接入playwright类,修改ui_components.py,整合到main.py

昨天已经要多上下文,单上下文的模块中测试成功了,今天要想法接入。 整理完成的所有代码如下: 结构如图: main.py import sys from PyQt6 import QtWidgets from modules.ui_components import TableManager # 导入界面类 import asyncio# 在主函数中使用 qasync 整合事…

涨薪技术|使用Dockerfile创建镜像

上次的推文内容中介绍了如何使用docker commit的方法来构建镜像&#xff0c;相反推荐使用被称为Dockerfile的定义文件和docker build命令来构建镜像。Dockerfile使用基本的基于DSL语法的指令来构建一个Docker镜像&#xff0c;之后使用docker build命令基于该Dockerfile中的指令…

rkipc的h265设置

资料的位置 源代码在luckfox-pico/project/app/rkipc/rkipc/src/rv1106_ipc/video/video.c中&#xff0c;使用了rkmpi库&#xff0c;参考资料为"doc/zh/media/Rockchip_Developer_Guide_MPI.pdf" 通道设置设置 H265的通道设置主要由rkipc_pipe_0_init完成&#xf…

成都国际数字影像产业园:打造数字影像产业新高地

成都国际数字影像产业园&#xff1a;打造数字影像产业新高地 成都国际数字影像产业园正致力于构筑数字影像产业的新高地&#xff0c;成为推动区域数字经济发展的重要引擎。 核心定位与目标 该园区精准定位于数字影像文创产业&#xff0c;旨在打造集内容创作、技术研发、人才…

各类神经网络学习:(三)RNN 循环神经网络(中集),同步多对多结构的详细解释

上一篇下一篇RNN&#xff08;上集&#xff09;RNN&#xff08;下集&#xff09; 同步多对多结构 1&#xff09;结构详解 ①图解&#xff1a; ②参数含义&#xff1a; x t x_t xt​ &#xff1a;表示每一个时刻的输入&#xff1b; o t o_t ot​ &#xff1a;表示每一个时刻的输…

Perl 环境安装指南

Perl 环境安装指南 引言 Perl是一种广泛使用的解释型、动态编程语言,以其强大的文本处理能力和灵活性著称。本文将为您详细介绍Perl环境的安装过程,包括系统要求、安装步骤以及注意事项。 系统要求 在安装Perl之前,请确保您的计算机满足以下基本要求: 操作系统:Window…

【嵌入式学习2】C语言 - VScode环境搭建

目录 ## 语言分类 ## c语言编译器 ## VScode相关配置 ## 语言分类 编译型语言&#xff1a;C&#xff0c;C解释型语言&#xff1a;python&#xff0c;JS ## c语言编译器 分类GCC 系列MinGWCygwinMSVC系列一套编程语言编译器将GCC编译器和GNU Binutils移植到Win32平台下的产物…

qt+opengl 加载三维obj文件

1前面我们已经熟悉了opengl自定义顶点生成一个立方体&#xff0c;并且我们实现了立方体的旋转&#xff0c;光照等功能。下面我们来用opengl来加载一个obj文件。准备我们首先准备一个简单的obj文件&#xff08;head.obj&#xff09;。资源在本页下载 2 在obj文件里面&#xff0c…

0326-Java 字符串方法

package com.qc.字符串;import java.util.Arrays;public class Test {public static void main(String[] args) { // String x"hello";//字符串 char[] // x x"demo";//字符串拼接 // xx2450; // xxtrue; // System.out.println(x);//hellodemo2450t…

<command-line>:0:1: error: macro names must be identifiers m

报错&#xff1a;:0:1: error: macro names must be identifiers 排查类很久 原来是&#xff1a; add_compile_definitions(_GLIBCXX_USE_CXX11_ABI$ABI_VERSION)写成了 add_compile_definitions(-D_GLIBCXX_USE_CXX11_ABI$ABI_VERSION)多了个 -D。

风光互补智慧路灯的灯杆设计有哪些要求?

嘿&#xff0c;朋友们&#xff01;叁仟风光互补智慧路灯的灯杆设计那可是超级重要的事儿&#xff0c;得全方位综合考量各种因素&#xff0c;就是为了确保咱们的路灯能兼具超棒的功能性、绝对的安全性、无敌的美观性以及超厉害的耐用性&#xff01;下面就来看看这些超赞的常见要…

06、RAG

LLM的知识仅限于它所接受到的训练数据。如果我们希望让它了解特定领域的专有知识&#xff0c;则可以使用下面的方式操作&#xff1a; 使用RAG使用专有数据对LLM进行微调RAG与数据微调方式结合使用 什么是RAG 简单地说&#xff0c;RAG就是把数据发送给LLM之前从数据中查找相关…

自然语言处理:第一百零二章 如何去掉DeepSeek R1思考过程

本人项目地址大全&#xff1a;Victor94-king/NLP__ManVictor: CSDN of ManVictor 写在前面: 笔者更新不易&#xff0c;希望走过路过点个关注和赞&#xff0c;笔芯!!! 写在前面: 笔者更新不易&#xff0c;希望走过路过点个关注和赞&#xff0c;笔芯!!! 写在前面: 笔者更新不易…

flink 安装与访问 ui

官方文档&#xff1a;First steps | Apache Flink 版本&#xff1a;v2.0.0 下载Flink Flink运行在所有类UNIX环境中&#xff0c;即Linux&#xff0c;Mac OS X和Cygwin&#xff08;适用于Windows&#xff09;。您需要安装Java 11。要检查安装的Java版本&#xff0c;请在终端中…

WPF TextBox实现键盘enter后实时读取TextBox中的值

代码 <TextBox Grid.Column"0" x:Name"textBox" Margin"10,5,0,5" TextWrapping"Wrap" Text"{Binding SendMessage,UpdateSourceTriggerPropertyChanged}" VerticalContentAlignment"Center" CaretBrush&qu…

PyTorch实现Transformer模型

首先&#xff0c;我得回顾一下Transformer的基本结构&#xff0c;确保自己没有记错。Transformer由编码器和解码器组成&#xff0c;每个编码器层包含多头自注意力机制和前馈网络&#xff0c;解码器层则还有编码器-解码器注意力。 接下来&#xff0c;用户需要的是手把手的代码解…