Android盒子開發,獲取網絡的信息(熱點,WIFI,有線)

Android盒子開發,網絡信息的獲取,比手機要困難許多。比如我們要獲取網卡地址,IP地址,MAC等,有的系統沒有直接接口
盒子的Launcher中需要接管便攜式WIFI熱點的開啓,那麼就需要獲取SSID,爲了保證我們Launcher中獲取的SSID和系統一致。
說多了,都是淚啊。
熱點的信息存放在/data/misc/wifi/hostapd.conf文件下,首先我想到的是使用IO流去讀取,但是沒有Root權限是無法讀取的,於是乎想了一個更新坑爹的方法,自己修改該文件的權限,具體代碼如下

**
 * @author xiongchengguang
 * @ClassName ReadConfig
 * @Descripton 讀取WIFI熱點的名字
 * @date 2016229日下午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();
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章