Android Auto OS 13 及更高版本包含的功能允许您: 配置和管理以太网。图 1 显示了一个示例网络 汽车示意图:
图 1. Android Auto 网络。
此图显示了 OEM 网络应用的调用方法
EthernetManager
类,用于配置和管理板载以太网网络
(eth0.1、eth0.2 和 eth0.3)。图 1 的其余部分不在
本文档。
设置默认的以太网网络设置
要设置默认网络设置,请使用
资源叠加层
config_ethernet_interfaces
:
<string-array translatable="false" name="config_ethernet_interfaces">
<!--
<item>eth1;12,13,14,15;ip=192.168.0.10/24 gateway=192.168.0.1 dns=4.4.4.4,8.8.8.8</item>
<item>eth2;;ip=192.168.0.11/24</item>
<item>eth3;12,13,14,15;ip=192.168.0.12/24;1</item>
-->
</string-array>
这个
示例显示了 config_ethernet_interfaces
资源叠加层,来自
config.xml
。
有关代码的要点
eth1
、eth2
和eth3
是要配置的网络接口的名称。- 连续的数字
12, 13, 14, 15
表示 网络 功能 启用状态。 ip=
、gateway=
和dns
用于设置初始 IP 地址、网关 和 DNS。
启用或停用网络接口
如需启用网络接口,请调用
EthernetManager.enableInterface()
:
public final class InterfaceEnabler {
private final Context mApplicationContext;
private final EthernetManager mEthernetManager;
private final OutcomeReceiver<String, EthernetNetworkManagementException> mOutcomeReceiver;
public InterfaceEnabler(Context applicationContext,
OutcomeReceiver<String, EthernetNetworkManagementException> outcomeReceiver) {
mApplicationContext = applicationContext;
mEthernetManager = applicationContext.getSystemService(EthernetManager.class);
mOutcomeReceiver = outcomeReceiver;
}
public void enableInterface(String ifaceName) {
mEthernetManager.enableInterface(ifaceName,
mApplicationContext.getMainExecutor(),
mOutcomeReceiver);
}
}
有关代码的要点
ifaceName
是要启用的网络接口的名称。getMainExecutor()
会返回应用上下文。OutcomeReceiver
是一个回调,用于传达返回 已更新的网络名称(成功时)或EthernetNetworkManagementException
(在成功时) 错误。
启用网络接口后,它会使用由
EthernetManager.updateConfiguration()
。如果未设置配置
由 EthernetManager.updateConfiguration()
触发,则该网络接口使用
资源叠加层 config_ethernet_interfaces
或默认以太网网络
配置。
要停用网络接口,请调用
EthernetManager.disableInterface()
:
public final class InterfaceEnabler {
private final Context mApplicationContext;
private final EthernetManager mEthernetManager;
private final OutcomeReceiver<String, EthernetNetworkManagementException> mOutcomeReceiver;
public InterfaceEnabler(Context applicationContext,
OutcomeReceiver<String, EthernetNetworkManagementException> outcomeReceiver) {
mApplicationContext = applicationContext;
mEthernetManager = applicationContext.getSystemService(EthernetManager.class);
mOutcomeReceiver = outcomeReceiver;
}
public void disableInterface(String ifaceName) {
mEthernetManager.disableInterface(ifaceName,
mApplicationContext.getMainExecutor(),
mOutcomeReceiver);
}
}
有关代码的要点
ifaceName
是要停用的网络接口的名称。getMainExecutor()
会返回应用上下文。OutcomeReceiver
是一个回调,用于传达是否完成返回 已更新的网络名称(成功时)或EthernetNetworkManagementException
(在成功时) 错误。
更新网络配置
更新
以太网网络配置、调用
EthernetManager.updateConfiguration()
:
public final class ConfigurationUpdater {
private final Context mApplicationContext;
private final EthernetManager mEthernetManager;
private final OutcomeReceiver<String, EthernetNetworkManagementException> mCallback;
public ConfigurationUpdater(Context applicationContext,
OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
mApplicationContext = applicationContext;
mEthernetManager = applicationContext.getSystemService(EthernetManager.class);
mCallback = callback;
}
public void updateNetworkConfiguration(String packageNames,
String ipConfigurationText,
String networkCapabilitiesText,
String interfaceName)
throws IllegalArgumentException, PackageManager.NameNotFoundException {
EthernetNetworkUpdateRequest request = new EthernetNetworkUpdateRequest.Builder()
.setIpConfiguration(getIpConfiguration(ipConfigurationText))
.setNetworkCapabilities(getCapabilities(
interfaceName, networkCapabilitiesText, packageNames))
.build();
mEthernetManager.updateConfiguration(interfaceName, request,
mApplicationContext.getMainExecutor(), mCallback);
}
}
有关代码的要点
getCapabilities()
是一种辅助方法,用于获取当前网络 功能并调用convertToUIDs()
进行转换 将软件包名称转换为 Linux 唯一标识符 (UID)。通常情况下 不了解 UID 针对其关联的软件包进行预付费因此,如果您希望使用EthernetManager.updateConfiguration()
即可限制对部分应用的访问权限, 需要使用其 UIDrequest
是要用于内部网络的配置。通过 请求中可以包含 IP 配置和网络的新设置 功能。如果 该网络已在连接堆栈中注册,它会按照 配置。此配置不会在重新启动后保留。getMainExecutor()
会返回在其上调用监听器的执行器。mCallback
是用于传达返回结果的完成情况的回调 已更新的网络名称(成功时)或EthernetNetworkManagementException
(在成功时) 错误。
updateConfiguration()
可能会更新所考虑的网络的特征
不可变。通过
这些不可变特性会关闭、更新和恢复网络。
要更新的属性。
仅限部分应用使用网络
您可以使用 EthernetManager#updateConfiguration
将访问权限限制为
允许的 UID 的子集。使用这种方法可以涵盖以下使用情形:
需要。例如,对于只有一小部分用户能够使用的内部车载网络
众多原始设备制造商 (OEM) 应用。
Android 主要通过应用的 UID 跟踪应用。
以下代码
UIDToPackageNameConverter.java
展示了如何从软件包名称字符串中获取一系列 UID:
public static Set<Integer> convertToUids(Context applicationContext, String packageNames)
throws PackageManager.NameNotFoundException {
final PackageManager packageManager = applicationContext.getPackageManager();
final UserManager userManager = applicationContext.getSystemService(UserManager.class);
final Set<Integer> uids = new ArraySet<>();
final List<UserHandle> users = userManager.getUserHandles(true);
String[] packageNamesArray = packageNames.split(",");
for (String packageName : packageNamesArray) {
boolean nameNotFound = true;
packageName = packageName.trim();
for (final UserHandle user : users) {
try {
final int uid =
packageManager.getApplicationInfoAsUser(packageName, 0, user).uid;
uids.add(uid);
nameNotFound = false;
} catch (PackageManager.NameNotFoundException e) {
// Although this may seem like an error scenario, it is OK as all packages are
// not expected to be installed for all users.
continue;
}
}
if (nameNotFound) {
throw new PackageManager.NameNotFoundException("Not installed: " + packageName);
}
}
return uids;
有关代码的要点
getApplicationInfoAsuser().uid
用于从 软件包名称uids
是生成的整数数组。
以下代码
EthernetManagerTest.kt
展示了如何使用应用的 UID 更新网络接口配置
获准使用网络:
val allowedUids = setOf(Process.myUid())
val nc = NetworkCapabilities.Builder(request.networkCapabilities)
.setAllowedUids(allowedUids).build()
updateConfiguration(iface, capabilities = nc).expectResult(iface.name)
其中:
allowUids
是允许使用网络的一组应用 UID。updateConfiguration()
会更新配置以将网络限制为 提供的一组 UID。