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เป็น Callback ที่ใช้เพื่อสื่อสารการดำเนินการให้เสร็จสมบูรณ์โดยแสดงชื่อเครือข่ายที่อัปเดตแล้วเมื่อสำเร็จ หรือ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เป็น Callback ที่ใช้เพื่อสื่อสารการดำเนินการให้เสร็จสมบูรณ์โดยแสดงชื่อเครือข่ายที่อัปเดตแล้วเมื่อสำเร็จ หรือ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()เพื่อแปลง ชื่อแพ็กเกจที่มนุษย์อ่านได้เป็นตัวระบุที่ไม่ซ้ำกัน (UID) ของ Linux โดยปกติแล้ว คุณจะไม่ทราบ UID ล่วงหน้าสำหรับแพ็กเกจที่เกี่ยวข้อง ดังนั้น หากต้องการใช้EthernetManager.updateConfiguration()เพื่อจำกัดการเข้าถึงแอปบางส่วน คุณ ต้องใช้ UID ของแอปเหล่านั้นrequestคือการกำหนดค่าที่จะใช้สำหรับเครือข่ายภายใน คำขออาจมีการตั้งค่าใหม่สำหรับการกำหนดค่า IP และความสามารถของเครือข่าย หาก เครือข่ายลงทะเบียนกับสแต็กการเชื่อมต่อ ระบบจะอัปเดตตาม การกำหนดค่า การกำหนดค่านี้จะไม่คงอยู่เมื่อรีบูตgetMainExecutor()จะแสดงผลตัวดำเนินการที่เรียกใช้ ListenermCallbackคือ Callback ที่ใช้ในการสื่อสารการดำเนินการเสร็จสิ้นโดยส่งคืน ชื่อเครือข่ายที่อัปเดตแล้วเมื่อสำเร็จ หรือEthernetNetworkManagementExceptionเมื่อเกิด ข้อผิดพลาด
updateConfiguration() อาจอัปเดตลักษณะของเครือข่ายที่สแต็กการเชื่อมต่อ Android ถือว่า
เปลี่ยนแปลงไม่ได้
ระบบจะปิดเครือข่าย อัปเดต และเปิดอีกครั้งเพื่อให้มีการอัปเดตแอตทริบิวต์ที่แก้ไขไม่ได้เหล่านี้
จำกัดเครือข่ายให้ใช้ได้กับแอปบางส่วน
คุณสามารถใช้ 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ใช้เพื่อดึงข้อมูล 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 ที่ระบุ