rk3288 android10 以太网启用/禁用app添加 发表于 2026-07-25 | 更新于 2026-08-17
| 阅读量:
1. framework 层修改,添加 app 所需的控制接口
修改 frameworks/base/core/java/android/net/IEthernetManager.aidl
1 2 3 4 5 6 7 8 interface IEthernetManager { // ... 原有代码 ... //为新方法添加AIDL接口 void setEthernetEnabled(boolean enabled); boolean isEthernetEnabled(); }
修改 frameworks/base/core/java/android/net/EthernetManager.java
添加方法 setEthernetEnabled 和 isEthernetEnabled 注意注释中的@hide 不要省略
在 Java 开发中,*@hide* 是一种特殊的 Javadoc 注释,用于隐藏某些类、方法或字段,使其在生成的 API 文档中不可见。尽管这些元素在代码中是公开的,但通过 @hide 注释可以避免它们被外部开发者误用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 @SystemService(Context.ETHERNET_SERVICE) public class EthernetManager { public void setEthernetEnabled (boolean enabled) { try { mService.setEthernetEnabled(enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } public boolean isEthernetEnabled () { try { return mService.isEthernetEnabled(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } }
修改 frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetServiceImpl.java
添加成员变量``mEthernetEnabled、方法setEthernetEnabled和方法isEthernetEnabled`。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public class EthernetServiceImpl extends IEthernetManager .Stub { private boolean mEthernetEnabled = true ; @Override public void setEthernetEnabled (boolean enabled) { enforceConnectivityInternalPermission(); if (mEthernetEnabled == enabled) return ; mEthernetEnabled = enabled; mTracker.setEthernetEnabled(enabled); } @Override public boolean isEthernetEnabled () { return mEthernetEnabled; } }
修改 frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetTracker.java
在方法 getInterfaces 添加 setEthernetEnabled
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 final class EthernetTracker { String[] getInterfaces(boolean includeRestricted) { return mFactory.getAvailableInterfaces(includeRestricted); } void setEthernetEnabled (boolean enabled) { String[] ifaces = getInterfaces(true ); for (String iface : ifaces) { try { if (enabled) { mNMService.setInterfaceUp(iface); Log.i(TAG, "Interface " + iface + " brought UP" ); } else { mNMService.setInterfaceDown(iface); Log.i(TAG, "Interface " + iface + " brought DOWN" ); } } catch (RemoteException e) { Log.e(TAG, "Failed to set interface state for " + iface, e); } } } }
将编译好的 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar 添加到 Android Studio 项目 EthernetControl/app/libs/framework.jar
记得在 build.gradle 导入该 jar 包使用 compileOnly 表示只用于编译不打包进 apk
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 plugins { id 'com.android.application' } android { compileSdkVersion 29 buildToolsVersion "29.0.3" defaultConfig { applicationId "com.rk3288.ethernetcontrol" minSdkVersion 29 targetSdkVersion 29 versionCode 1 versionName "1.0" } // 签名配置 signingConfigs { platform { storeFile file("rk3288_android10.jks") storePassword "123456" keyAlias "rk3288_android10" keyPassword "123456" } } buildTypes { debug { signingConfig signingConfigs.platform } release { signingConfig signingConfigs.platform minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } lintOptions { checkReleaseBuilds false abortOnError false } } dependencies { compileOnly files('libs/framework.jar') }
2.app 代码(可以使用生成好的 apk, 该信息用于后期修改查看) 主要的 MainActivity.java 代码,且 app 也只有该代码实现全部业务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 package com.rk3288.ethernetcontrol;import android.app.Activity;import android.content.Context;import android.net.EthernetManager;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.CompoundButton;import android.widget.Switch;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity { private static final String TAG = "EthernetControl" ; private static final String ETH_IFACE = "eth0" ; private static final String ETH_SERVICE = "ethernet" ; private Switch mEthernetSwitch; private TextView mStatusText; private TextView mDetailText; private Button mRefreshBtn; private EthernetManager mEthernetManager; private Handler mHandler = new Handler (Looper.getMainLooper()); @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); initEthernetManager(); refreshStatus(); } private void initViews () { mEthernetSwitch = findViewById(R.id.ethernet_switch); mStatusText = findViewById(R.id.status_text); mDetailText = findViewById(R.id.detail_text); mRefreshBtn = findViewById(R.id.refresh_btn); mEthernetSwitch.setOnCheckedChangeListener(new CompoundButton .OnCheckedChangeListener() { @Override public void onCheckedChanged (CompoundButton buttonView, boolean isChecked) { if (!buttonView.isPressed()) return ; setEthernetState(isChecked); } }); mRefreshBtn.setOnClickListener(new View .OnClickListener() { @Override public void onClick (View v) { refreshStatus(); Toast.makeText(MainActivity.this , "Status refreshed" , Toast.LENGTH_SHORT).show(); } }); } private void initEthernetManager () { mEthernetManager = (EthernetManager) getSystemService(ETH_SERVICE); if (mEthernetManager == null ) { showError("Failed to get EthernetManager service" ); return ; } if (!isEthernetAvailable()) { showError("No Ethernet interface detected (" + ETH_IFACE + ")" ); mEthernetSwitch.setEnabled(false ); } } private boolean isEthernetAvailable () { try { String[] interfaces = mEthernetManager.getAvailableInterfaces(); if (interfaces == null || interfaces.length == 0 ) { return false ; } for (String iface : interfaces) { if (ETH_IFACE.equals(iface)) { return true ; } } return false ; } catch (Exception e) { Log.e(TAG, "Failed to check ethernet availability" , e); return false ; } } private void setEthernetState (boolean enabled) { try { Log.d(TAG, "setEthernetState called: " + enabled); try { Log.d(TAG, "Calling setEthernetEnabled..." ); mEthernetManager.setEthernetEnabled(enabled); Log.d(TAG, "setEthernetEnabled returned successfully" ); } catch (Exception e) { Log.e(TAG, "setEthernetEnabled failed" , e); } String msg = enabled ? "Ethernet enabled" : "Ethernet disabled, Wi-Fi will take over" ; Toast.makeText(this , msg, Toast.LENGTH_SHORT).show(); mHandler.postDelayed(new Runnable () { @Override public void run () { refreshStatus(); } }, 1000 ); } catch (Exception e) { Log.e(TAG, "Failed to set ethernet state" , e); Toast.makeText(this , "Operation failed: " + e.getMessage(), Toast.LENGTH_LONG).show(); mHandler.postDelayed(new Runnable () { @Override public void run () { refreshStatus(); } }, 500 ); } } private void refreshStatus () { try { boolean isEnabled = mEthernetManager.isEthernetEnabled(); mEthernetSwitch.setChecked(isEnabled); StringBuilder detail = new StringBuilder (); detail.append("Interface: " ).append(ETH_IFACE).append("\n" ); detail.append("System State: " ).append(isEnabled ? "Enabled" : "Disabled" ).append("\n" ); try { String ip = mEthernetManager.getIpAddress(ETH_IFACE); if (ip != null && !ip.isEmpty()) { detail.append("IP: " ).append(ip).append("\n" ); } String netmask = mEthernetManager.getNetmask(ETH_IFACE); if (netmask != null && !netmask.isEmpty()) { detail.append("Netmask: " ).append(netmask).append("\n" ); } String gateway = mEthernetManager.getGateway(ETH_IFACE); if (gateway != null && !gateway.isEmpty()) { detail.append("Gateway: " ).append(gateway).append("\n" ); } String dns = mEthernetManager.getDns(ETH_IFACE); if (dns != null && !dns.isEmpty()) { detail.append("DNS: " ).append(dns).append("\n" ); } } catch (Exception e) { detail.append("Network details unavailable" ).append("\n" ); } mStatusText.setText(isEnabled ? "Ethernet Enabled" : "Ethernet Disabled" ); mStatusText.setTextColor(isEnabled ? 0xFF4CAF50 : 0xFFF44336 ); mDetailText.setText(detail.toString()); } catch (Exception e) { Log.e(TAG, "Failed to refresh status" , e); mStatusText.setText("Status unavailable" ); mStatusText.setTextColor(0xFFF44336 ); mDetailText.setText("Error: " + e.getMessage()); } } private void showError (String msg) { mStatusText.setText(msg); mStatusText.setTextColor(0xFFF44336 ); Toast.makeText(this , msg, Toast.LENGTH_LONG).show(); } @Override protected void onResume () { super .onResume(); refreshStatus(); } }
注意: app 签名教程:请查看 apk签名.md 文档
3. 将 app 添加到系统预装
1 2 3 4 5 mkdir -p device/rockchip/rk3288/rk3288_Android10/EthernetControlcp app-signed.apk device/rockchip/rk3288/rk3288_Android10/EthernetControl
1 2 3 4 5 6 7 8 9 10 LOCAL_PATH := $(call my-dir ) include $(CLEAR_VARS) LOCAL_MODULE := EthernetControl LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(LOCAL_MODULE) .apk LOCAL_MODULE_CLASS := APPS LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX) LOCAL_CERTIFICATE := platform LOCAL_PRIVILEGED_MODULE := true include $(BUILD_PREBUILT)
将该文件创建在 device/rockchip/rk3288/rk3288_Android10/EthernetControl 路径下
在 device/rockchip/rk3288/rk3288_Android10/rk3288_Android10.mk 中添加:
1 PRODUCT_PACKAGES += EthernetControl
4.业务流程(可忽略) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 ┌─────────────────────────────────────────────────────────────────────────────┐ │ APP 层 │ │ com.rk3288.ethernetcontrol.MainActivity │ │ │ │ │ ▼ │ │ getSystemService("ethernet") ──► EthernetManager │ │ │ │ │ ▼ │ │ mService.setEthernetEnabled(false) ──► IPC (Binder) │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ AIDL 接口层 │ │ IEthernetManager.aidl │ │ ├─ setEthernetEnabled(boolean enabled) ◄── App 调用 │ │ └─ isEthernetEnabled() ◄── App 查询 │ │ │ │ │ ▼ │ │ 编译后生成 IEthernetManager.Stub / IEthernetManager.Stub.Proxy │ │ 负责 Binder 序列化/反序列化 │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 服务端实现层 (system_server) │ │ EthernetServiceImpl extends IEthernetManager.Stub │ │ ├─ setEthernetEnabled(boolean enabled) │ │ │ ├── enforceConnectivityInternalPermission() // 权限检查 │ │ │ ├── mEthernetEnabled = enabled // 保存状态 │ │ │ └── mTracker.setEthernetEnabled(enabled) // 调用 Tracker │ │ │ │ │ └─ isEthernetEnabled() │ │ └── return mEthernetEnabled │ │ │ │ │ ▼ │ │ EthernetTracker │ │ ├─ setEthernetEnabled(boolean enabled) │ │ │ └── 遍历所有接口: │ │ │ enabled ? mNMService.setInterfaceUp(iface) │ │ │ : mNMService.setInterfaceDown(iface) // 物理控制网口 │ │ │ │ │ ├─ mNMService = INetworkManagementService.Stub.asInterface(...) │ │ │ └── 最终调用 NetworkManagementService (netd) │ │ │ │ │ └─ InterfaceObserver │ │ └── interfaceLinkStateChanged() / interfaceAdded() / interfaceRemoved() │ │ └── 驱动事件回调,管理网络代理生命周期 │ │ │ │ │ ▼ │ │ EthernetNetworkFactory extends NetworkFactory │ │ ├─ addInterface() // 注册网络代理 │ │ ├─ removeInterface() // 注销网络代理 │ │ ├─ updateInterfaceLinkState() // 链路状态变化 │ │ └─ NetworkInterfaceState // 内部类,管理单个网口的 IP/代理/评分 │ │ ├─ start() // 启动 IpClient,申请 IP │ │ ├─ stop() // 停止 IpClient,注销 NetworkAgent │ │ └─ updateLinkState() // 根据链路 up/down 启停 │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 内核/驱动层 │ │ NetworkManagementService (system_server ──► netd ──► kernel) │ │ ├─ setInterfaceDown("eth0") │ │ │ └── ioctl(SIOCSIFFLAGS) 清除 IFF_UP 标志 │ │ │ └── 网口 PHY/MAC 关闭,LED 熄灭 │ │ │ │ │ └─ setInterfaceUp("eth0") │ │ └── ioctl(SIOCSIFFLAGS) 设置 IFF_UP 标志 │ │ └── 网口 PHY/MAC 启动,LED 亮起 │ │ │ │ │ ▼ │ │ 驱动上报 netlink 事件 ──► InterfaceObserver 回调 │ │ ──► ConnectivityService 重新评估网络 ──► Wi-Fi 接管 │ └─────────────────────────────────────────────────────────────────────────────┘