Tucao, parece que el funcionario no tiene el proceso de configuración de Ethernet y WiFi. Esta parte de la configuración de la red se basa principalmente en
Settings
el contenido de
La configuración de Ethernet requiere el uso de EthernetManager
clases, veamos las características de esta clase:
/**
* A class representing the IP configuration of the Ethernet network.
*
* @hide
*/
@SystemApi
@TestApi
@SystemService(Context.ETHERNET_SERVICE)
public class EthernetManager
Esta clase no está abierta a aplicaciones normales y requiere algunos permisos especiales.
Preparación ambiental
- Para la configuración de red estática, primero debe configurar la aplicación como nivel de sistema
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxxx.xxxx"
android:sharedUserId="android.uid.system">
- Dado que
EthernetManager
se usa la clase, esta clase seAndroid
define como oculta, por lo que debemos confiar en unaframework.jar
.
compileOnly files('frameworks.jar')
compileOnly
lata
- En este momento
AS
, todavía mostrará que no se puede encontrarEthernetManager
AS
module
Un.yml
archivo en cada administrado- Simplemente ponga el orden en el
.yml
archivoframework.jar
al principio
Me gusta esto
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Gradle: ./../../fm-libs/ironman_frameworks.jar" level="project" />
//......
<orderEntry type="module" module-name="factory_test_interf" />
<orderEntry type="jdk" jdkName="Android API 29 Platform" jdkType="Android SDK" />
De esta forma AS
se dará prioridad a framework.jar
la clase en la búsqueda .
Si comienza a compilar, también debe aparecer no puede encontrar la clase, entonces también necesitamos que Project
se build.gradle
lleve a cabo de la siguiente manera:
allprojects {
repositories {
//......
}
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
//......
options.compilerArgs.add('-Xbootclasspath/p:/Users/lijie/fm-libs/frameworks.jar')
}
}
}
Esto debería encontrar framework.jar
la clase en el tiempo de compilación.
Inicio de código
- Una clase de interfaz
NetworkConfiguration
, delSettings
dibujo.
import android.net.IpConfiguration;
import android.net.wifi.WifiManager;
/**
* Provide unified interface for network configuration that works for both Wi-Fi and Ethernet.
*/
public interface NetworkConfiguration {
/**
* Set IpConfiguration
*
* @param configuration IpConfiguration to set
*/
public void setIpConfiguration(IpConfiguration configuration);
/**
* Get IpConfiguration
*
* @return IpConfiguration
*/
public IpConfiguration getIpConfiguration();
/**
* Save current network configuration to system
*
* @param listener listener to notify the result
*/
public void save(WifiManager.ActionListener listener);
/**
* Get printable name for this network.
*
* @return Printable name
*/
public String getPrintableName();
}
- Clase de implementación de configuración Ethernet
EthernetConfig
, que implementa laNetworkConfiguration
interfaz
import android.content.Context;
import android.net.EthernetManager;
import android.net.IpConfiguration;
import android.net.wifi.WifiManager;
import android.os.Looper;
/**
* Ethernet configuration that implements NetworkConfiguration.
*/
class EthernetConfig implements NetworkConfiguration {
private EthernetManager mEthernetManager;
private IpConfiguration mIpConfiguration;
private String mName;
private String mInterfaceName;
EthernetConfig(Context context) {
if (Thread.currentThread().getId() != context.getMainLooper().getThread().getId()) {
// 由于 EthernetManager 在初始化的时候会启动一个Handler
// 如果不是在主线程中,并且没有调用Looper.prepare(),会出现异常
if (Looper.myLooper() == null) {
Looper.prepare();
}
}
mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);
mIpConfiguration = new IpConfiguration();
mName = "Ethernet";
}
@Override
public IpConfiguration getIpConfiguration() {
return mIpConfiguration;
}
@Override
public void setIpConfiguration(IpConfiguration configuration) {
mIpConfiguration = configuration;
}
@Override
public void save(WifiManager.ActionListener listener) {
if (mInterfaceName != null) {
mEthernetManager.setConfiguration(mInterfaceName, mIpConfiguration);
}
if (listener != null) {
listener.onSuccess();
}
}
/**
* Load IpConfiguration from system.
*/
public void load() {
String[] ifaces = mEthernetManager.getAvailableInterfaces();
if (ifaces.length > 0) {
mInterfaceName = ifaces[0];
mIpConfiguration = mEthernetManager.getConfiguration(mInterfaceName);
}
}
@Override
public String getPrintableName() {
return mName;
}
}
- La clase de herramienta del proceso de configuración
EthernetUtils
, los comentarios son muy detallados.
import android.content.Context;
import android.net.IpConfiguration;
import android.net.LinkAddress;
import android.net.StaticIpConfiguration;
import android.net.wifi.WifiManager;
import android.text.TextUtils;
import android.util.Log;
import java.net.Inet4Address;
import java.util.concurrent.CountDownLatch;
import static com.fengmi.factory_test_interf.sdk_utils.NetworkUtil.netMask2Length;
public final class EthernetUtils {
private static final String TAG = "EthernetUtils";
private static volatile boolean res = false;
private EthernetUtils() {
}
/**
* 设置 IP 获取方式为 DHCP 动态分配
*
* @param context 上下文对象
* @return 配置是否保存成功
*/
public static boolean saveDHCPEthernetConfig(Context context) {
res = false;
//1. 创建一个EthernetConfig对象
EthernetConfig netConfig = new EthernetConfig(context);
//2. load 加载系统配置到对象中
netConfig.load();
//3. 设置IP获取方式为 DHCP
netConfig.getIpConfiguration().setIpAssignment(IpConfiguration.IpAssignment.DHCP);
//4. 设置一个等待latch
CountDownLatch latch = new CountDownLatch(1);
//5. 保存配置到系统,并监听是否设置成功
netConfig.save(new WifiManager.ActionListener() {
@Override
public void onSuccess() {
Log.d(TAG, "set IP assignment DHCP success");
res = true;
latch.countDown();
}
@Override
public void onFailure(int i) {
Log.d(TAG, "set IP assignment DHCP failed, code=" + i);
res = false;
latch.countDown();
}
});
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return res;
}
/**
* 设置以太网静态IP<p/>
* 网上都没能找到正规的流程说明,从Settings中借鉴来的代码<p/>
* 人性化的我添加了注释,吼吼吼<p/>
* 网络配置相关的科普链接{https://blog.51cto.com/zhoutao/93629}
*
* @param context 上下文
* @param ipAddress ip 地址,格式为:10.10.10.10
* @param netMask 子网掩码,格式为:255.255.255.0
* @param gateway 默认网关,格式为:10.10.10.1
* @param dns dns服务地址,google 提供了两个免费的
* @return 配置是否成功
*/
public static boolean saveStaticEthernetConfig(Context context,
String ipAddress,
String netMask,
String gateway,
String dns) {
res = false;
// 创建一个 StaticIpConfiguration 对象,用来保存静态IP相关的信息
StaticIpConfiguration staticConfig = new StaticIpConfiguration();
// 创建一个EthernetConfig对象
EthernetConfig netConfig = new EthernetConfig(context);
// load 加载系统配置到对象中
netConfig.load();
// 关联配置信息对象
netConfig.getIpConfiguration().setStaticIpConfiguration(staticConfig);
// 针对 IP地址 做一些异常判断
if (TextUtils.isEmpty(ipAddress)) {
Log.i(TAG, "empty ipv4 addr");
return false;
}
// 根据子网掩码计算Prefix Length,看看究竟掩护了多少位
// 其实就是计算子网掩码比特位为1的位数。
int networkPrefixLength;
try {
networkPrefixLength = netMask2Length(netMask);
} catch (Exception e) {
e.printStackTrace();
return false;
}
//根据 IP 和 子网掩码的Prefix Length信息 生成 ipAddress 对象
Inet4Address inetAddr;
try {
// 将IP 转化为 Inet4Address 对象
inetAddr = (Inet4Address) android.net.NetworkUtils.numericToInetAddress(ipAddress);
// 将 `Inet4Address 对象` 和 `子网掩码的Prefix Length信息` 打包成LinkAddress对象
// 赋值给 StaticIpConfiguration 对象中的 ipAddress
staticConfig.ipAddress = new LinkAddress(inetAddr, networkPrefixLength);
} catch (IllegalArgumentException | ClassCastException e) {
e.printStackTrace();
return false;
}
// 将网关信息设置给 StaticIpConfiguration 对象中的 gateway
if (!TextUtils.isEmpty(gateway)) {
try {
staticConfig.gateway =
android.net.NetworkUtils.numericToInetAddress(gateway);
} catch (IllegalArgumentException | ClassCastException e) {
e.printStackTrace();
return false;
}
}
//将 dns 添加到 StaticIpConfiguration 对象的 DNS 服务列表中
if (!TextUtils.isEmpty(dns)) {
try {
staticConfig.dnsServers.add(
android.net.NetworkUtils.numericToInetAddress(dns));
} catch (IllegalArgumentException | ClassCastException e) {
e.printStackTrace();
return false;
}
}
// 添加两个Google提供的免费DNS服务器的IP地址
try {
staticConfig.dnsServers.add(
android.net.NetworkUtils.numericToInetAddress("8.8.8.8"));
staticConfig.dnsServers.add(
android.net.NetworkUtils.numericToInetAddress("8.8.4.4"));
} catch (IllegalArgumentException | ClassCastException e) {
e.printStackTrace();
return false;
}
// 设置 IpAssignment 为 Static 模式
netConfig.getIpConfiguration().setIpAssignment(IpConfiguration.IpAssignment.STATIC);
// 设置一个等待latch
CountDownLatch latch = new CountDownLatch(1);
// 保存配置信息到系统,并监听设置结果
netConfig.save(new WifiManager.ActionListener() {
@Override
public void onSuccess() {
Log.d(TAG, "set static IP assignment success");
res = true;
latch.countDown();
}
@Override
public void onFailure(int i) {
Log.d(TAG, "set static IP assignment failed, code=" + i);
res = false;
latch.countDown();
}
});
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return res;
}
/**
* 计算子网掩码的 Prefix Length
*
* @param netMask 子网掩码
* @return Prefix Length
*/
private static int netMask2Length(String netMask) {
byte[] array = netMask2ByteArray(netMask);
if (array == null) {
return -1;
}
int i = array[0] << 24 | array[1] << 16 | array[2] << 8 | array[3];
int j = 32;
int k = 1;
while (((i & k) == 0) && (k != 0)) {
k <<= 1;
j--;
}
return j;
}
/**
* 将子网掩码转化为字节数组
*
* @param str 子网掩码
* @return 字符数组,格式不正确返回null
*/
private static byte[] netMask2ByteArray(String str) {
if (str == null || str.length() == 0) {
return null;
}
StringTokenizer tokenizer = new StringTokenizer(str, ".");
if (tokenizer.countTokens() != 4) {
return null;
}
byte[] arrayOfByte = new byte[4];
for (int i = 0; tokenizer.hasMoreTokens(); i++) {
int j = Integer.parseInt(tokenizer.nextToken());
arrayOfByte[i] = (byte) j;
}
return arrayOfByte;
}
}
para resumir
Quiere completar esta función
- Se
EthernetManager
necesita algo de tiempo para importar clases ocultas. - Lleva algún tiempo familiarizarse con los términos relacionados con la configuración de la red.
- dirección IP
- Máscara de subred
- Puerta de enlace predeterminada
- dns
- Lleva algún tiempo familiarizarse con el proceso de configuración
- Primero cargue la configuración de red del sistema
- Luego configure los parámetros de red correspondientes
- Luego configure diferentes tipos
- DHCP
- ESTÁTICO
- Finalmente guarda la configuración
La prueba actual está disponible y la implementación de WiFi es similar a este proceso, aunque la función se ha completado, todavía hay algunas dudas en el proceso, así que no la publicaré primero, ¡jeje!