Android盒子開發,網絡信息的獲取,比手機要困難許多。比如我們要獲取網卡地址,IP地址,MAC等,有的系統沒有直接接口
盒子的Launcher中需要接管便攜式WIFI熱點的開啓,那麼就需要獲取SSID,爲了保證我們Launcher中獲取的SSID和系統一致。
說多了,都是淚啊。
熱點的信息存放在/data/misc/wifi/hostapd.conf文件下,首先我想到的是使用IO流去讀取,但是沒有Root權限是無法讀取的,於是乎想了一個更新坑爹的方法,自己修改該文件的權限,具體代碼如下
**
* @author xiongchengguang
* @ClassName ReadConfig
* @Descripton 讀取WIFI熱點的名字
* @date 2016年2月29日下午3:16:23
*/
public class ReadConfig {
private static final String TAG = "ReadConfig";
public static String loadFileAsString() {
getRootPermission();
StringBuffer sb = new StringBuffer();
String ssid ="";
try {
BufferedReader reader = new BufferedReader(new FileReader("/data/misc/wifi/hostapd.conf"));
char[] buf = new char[8192];
int len = 0;
while ((len = reader.read(buf)) != -1) {
String str = String.valueOf(buf, 0, len);
sb.append(str);
}
reader.close();
int index=sb.toString().indexOf("ssid")+5;
int end=sb.toString().indexOf("channel");
ssid=sb.toString().substring(index, end);
} catch (Exception e) {
e.printStackTrace();
}
Log.d(TAG, ssid);
return ssid;
}
/**
* 修改系統文件權限
*/
private static void getRootPermission(){
Process process;
DataOutputStream dataOutputStream;
try {
String cmd1="chmod 777 /data";
String cmd2="chmod 777 /data/misc/";
String cmd3="chmod 777 /data/misc/wifi/";
String cmd4="chmod 777 /data/misc/wifi/hostapd.conf";
process=Runtime.getRuntime().exec("su");
dataOutputStream=new DataOutputStream(process.getOutputStream());
dataOutputStream.writeBytes(cmd1+"\n");
dataOutputStream.writeBytes(cmd2+"\n");
dataOutputStream.writeBytes(cmd3+"\n");
dataOutputStream.writeBytes(cmd4+"\n");
dataOutputStream.writeBytes("exit\n");
dataOutputStream.flush();
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
但是這樣就會出現一個問題,有的時候能讀取到,有的時候不行的。這樣程序丟給用戶有損我天朝的程序員的臉面啊
腦門一拍,把Setting的源碼打開看看不就好了嗎
那我們來看下別人具體實現,這不正是系統設置的UI佈局嗎上面一個TextVie用戶,下面一個EditText輸入框嗎
那我們下面開始使用上面的id來全局搜索 (Ctrl+H ->wifi_ap_dialog)
/**
* Dialog to configure the SSID and security settings
* for Access Point operation
*/
public class WifiApDialog extends AlertDialog implements View.OnClickListener,
TextWatcher, AdapterView.OnItemSelectedListener {
static final int BUTTON_SUBMIT = DialogInterface.BUTTON_POSITIVE ;
private final DialogInterface.OnClickListener mListener;
public static final int OPEN_INDEX = 0;
public static final int WPA_INDEX = 1;
public static final int WPA2_INDEX = 2;
private View mView;
private TextView mSsid;
private int mSecurityTypeIndex = OPEN_INDEX;
private EditText mPassword;
WifiConfiguration mWifiConfig;
public WifiApDialog(Context context, DialogInterface.OnClickListener listener ,
WifiConfiguration wifiConfig) {
super(context);
mListener = listener;
mWifiConfig = wifiConfig;
if (wifiConfig != null) {
mSecurityTypeIndex = getSecurityTypeIndex(wifiConfig);
}
}
.......省略
@Override
protected void onCreate(Bundle savedInstanceState) {
mView = getLayoutInflater().inflate(R.layout.wifi_ap_dialog, null);
Spinner mSecurity = ((Spinner) mView.findViewById(R.id. security));
setView( mView);
setInverseBackgroundForced( true);
Context context = getContext();
setTitle(R.string. wifi_tether_configure_ap_text);
mView.findViewById(R.id. type).setVisibility(View. VISIBLE);
mSsid = (TextView) mView.findViewById(R.id. ssid);
mPassword = (EditText) mView.findViewById(R.id. password);
setButton( BUTTON_SUBMIT, context.getString(R.string. wifi_save), mListener);
setButton(DialogInterface. BUTTON_NEGATIVE,
context.getString(R.string. wifi_cancel), mListener);
if (mWifiConfig != null) {
mSsid.setText( mWifiConfig. SSID);
mSecurity.setSelection( mSecurityTypeIndex);
if ( mSecurityTypeIndex == WPA_INDEX ||
mSecurityTypeIndex == WPA2_INDEX) {
mPassword.setText( mWifiConfig. preSharedKey);
}
}
.......省略
佈局中查找控件
mSsid = (TextView) mView.findViewById(R.id. ssid);
給控件賦值
mSsid.setText( mWifiConfig. SSID);
看到了關鍵的地方 mWifiConfig 這玩意兒是啊,繼續查找,終於在構造函數中找到了他,原來他是從別的地方傳遞過來的
public WifiApDialog(Context context, DialogInterface.OnClickListener listener ,
WifiConfiguration wifiConfig) {
那我們繼續找在什麼地方調用了WifiApDialog這個類 還是Ctrl+H全局查找
@Override
public Dialog onCreateDialog( int id) {
if (id == DIALOG_AP_SETTINGS) {
final Activity activity = getActivity();
mDialog = new WifiApDialog(activity, this, mWifiConfig);
return mDialog;
}
return null;
}
找到了調用地方,那我們在看看mWifiConfig哪兒來的
private void initWifiTethering() {
final Activity activity = getActivity();
mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE );
mWifiConfig = mWifiManager.getWifiApConfiguration();
原來是從getWifiApConfiguration這個方法獲取的getWifiApConfiguration實在WifiManager這個類中,繼續查找
/**
* Gets the Wi -Fi AP Configuration.
* @return AP details in WifiConfiguration
*
* @hide Dont open yet
*/
public WifiConfiguration getWifiApConfiguration() {
try {
return mService.getWifiApConfiguration();
} catch (RemoteException e) {
return null;
}
}
這可如何是好,這個方法是hide,上有政策,下有對策,高達上的技術出現了,反射來實現,具體代碼如下
private String getNetworkSSID() {
try {
Method method = wm.getClass().getMethod("getWifiApConfiguration");
method.setAccessible(true);
WifiConfiguration configuration = (WifiConfiguration) method.invoke(wm);
return configuration.SSID;
} catch (Exception e) {
e.printStackTrace();
}
return "net unknown";
}
完美解決問題
獲取其讓信息都比較簡單,有線的可能稍微複雜點。我直接貼出整個工具類的代碼,騷年們,複製,粘貼吧 不謝
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import java.io.BufferedReader;
import java.io.FileReader;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author xiongchengguang
* @ClassName NetorkUtils
* @Descripton 網絡工具類
* @date 2016年5月16日上午11:21:08
*/
public class NetworkUtils {
public static final int TYPE_AP = 0;
public static final int TYPE_WIFI = 1;
public static final int TYPE_NULL = -1;
public static final int TYPE_ETHERNET = 9;
public static final String NETWORK_TYPE = "network_type";
public static final String NETWORK_IP = "network_ip";
public static final String NETWORK_MAC = "network_mac";
public static final String NETWORK_NAME = "network_name";
private static WifiManager wm;
private static ConnectivityManager cm;
public static final String TAG = "NetorkUtils";
private static NetworkUtils instance = null;
private static Context context;
public static NetworkUtils getInstance(Context context) {
NetworkUtils.context = context;
initPlatform();
if (instance == null) {
synchronized (NetworkUtils.class) {
if (instance == null) {
instance = new NetworkUtils();
}
}
}
return instance;
}
private static void initPlatform() {
if (wm == null) {
wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
}
if (cm == null) {
cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
}
public int getNetworkType() {
if (isWifiApEnabled()) {
return TYPE_AP;
} else {
NetworkInfo info = cm.getActiveNetworkInfo();
if (info !=null && info.isConnected()) {
if (info.getType() == ConnectivityManager.TYPE_ETHERNET) {
return TYPE_ETHERNET;
} else if (info.getType() == ConnectivityManager.TYPE_WIFI) {
return TYPE_WIFI;
} else {
return TYPE_NULL;
}
} else {
return TYPE_NULL;
}
}
}
public String getNetworkName() {
String ssid = "net unknown";
int type = getNetworkType();
switch (type) {
case TYPE_AP:
ssid = getNetworkSSID();
break;
case TYPE_WIFI:
ssid = wm.getConnectionInfo().getSSID();
break;
case TYPE_ETHERNET:
ssid = "有線網絡";
break;
case TYPE_NULL:
ssid = "未知網絡";
break;
default:
break;
}
return ssid;
}
public String getNetworkIP(){
String address="";
int type = getNetworkType();
switch (type) {
case TYPE_AP:
address="192.168.43.1";
break;
case TYPE_WIFI:
int ip= wm.getConnectionInfo().getIpAddress();
address=((ip & 0xff) + "."+ (ip >> 8 & 0xff) + "."+ (ip >> 16 & 0xff) + "." + (ip >> 24 & 0xff));
break;
case TYPE_ETHERNET:
address=localAddress();
break;
case TYPE_NULL:
break;
default:
break;
}
return address;
}
public String getNetworkMac(){
String mac = "";
int type = getNetworkType();
switch (type) {
case TYPE_AP:
mac = wm.getConnectionInfo().getMacAddress();
if (mac == null) {
mac = UUID.randomUUID().toString();
}
break;
case TYPE_WIFI:
mac = wm.getConnectionInfo().getMacAddress();
if (mac == null) {
mac = UUID.randomUUID().toString();
}
break;
case TYPE_ETHERNET:
mac=localMac();
break;
case TYPE_NULL:
break;
default:
break;
}
return mac.toUpperCase();
}
private String getNetworkSSID() {
try {
Method method = wm.getClass().getMethod("getWifiApConfiguration");
method.setAccessible(true);
WifiConfiguration configuration = (WifiConfiguration) method.invoke(wm);
return configuration.SSID;
} catch (Exception e) {
e.printStackTrace();
}
return "net unknown";
}
public boolean isWifiApEnabled() {
try {
Method method = wm.getClass().getMethod("isWifiApEnabled");
method.setAccessible(true);
return (Boolean) method.invoke(wm);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public String loadReadFile(String path) {
StringBuffer sb = new StringBuffer();
try {
BufferedReader reader = new BufferedReader(new FileReader(path));
char[] buf = new char[8192];
int len = 0;
while ((len = reader.read(buf)) != -1) {
String str = String.valueOf(buf, 0, len);
sb.append(str);
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
public String localAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
Pattern p = Pattern.compile("^[1-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*$");
Matcher m = p.matcher(inetAddress.getHostAddress().toString());
if (!inetAddress.isLoopbackAddress() && m.matches()) {
return inetAddress.getHostAddress().toString();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public String localMac() {
try {
return loadReadFile("/sys/class/net/eth0/address").toUpperCase().substring(0, 17);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public Map getAllNetworkInfo(){
Map<String,Object> map=new HashMap<String, Object>();
map.put(NETWORK_TYPE, getNetworkType());
map.put(NETWORK_IP, getNetworkIP());
map.put(NETWORK_MAC, getNetworkMac());
map.put(NETWORK_NAME, getNetworkName());
return map;
}
public void startAP(){
if(wm.isWifiEnabled()){
startAP(getNetworkSSID(), "12345678");
}
}
private void startAP(String ssid, String password) {
Method method1 = null;
try {
method1 = wm.getClass().getMethod("setWifiApEnabled",WifiConfiguration.class, boolean.class);
WifiConfiguration netConfig = new WifiConfiguration();
netConfig.SSID = ssid;
netConfig.preSharedKey = password;
netConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
method1.invoke(wm, netConfig, true);
} catch (Exception e) {
e.printStackTrace();
}
}
}