Android6.0 Android7.0系统获getMacAddress()取Wifi和蓝牙Mac地址返回02:00:00:00:00:00解决办法

来源:互联网 发布:计算机程序员证书 编辑:程序博客网 时间:2024/05/14 18:16

   有一些比较老的app。在使用的过程中会出现 getmac 返回:  02:00:00:00 这样的一个值。导致这些app无法使用。在这些app没有更新的情况下。可以通过修改framework满足一些客户的定制app的使用

  造成这个问题的根本原因在于  6.0  以后的android 系统  getMacAddress();  这个api已经失效。如果是自己写应用。只需要更新api。换成6.0 以后支持的方法去获取就可以获取到mac地址。当然。我们这里讨论的是另外一种方式。客户提供较老的app给你,而这个app并没有源码的情况下。可以通过修改系统的framework来解决这个问题。

先看看wifiinfo这个类: 不想看直接跳到源码最后一行。

public class WifiInfo implements Parcelable {    private static final String TAG = "WifiInfo";    /**     * This is the map described in the Javadoc comment above. The positions     * of the elements of the array must correspond to the ordinal values     * of <code>DetailedState</code>.     */    private static final EnumMap<SupplicantState, DetailedState> stateMap =            new EnumMap<SupplicantState, DetailedState>(SupplicantState.class);    /**     * Default MAC address reported to a client that does not have the     * android.permission.LOCAL_MAC_ADDRESS permission.     *     * @hide     */    public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";    static {        stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED);        stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED);        stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE);        stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING);        stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING);        stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING);        stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING);        stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING);        stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING);        stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR);        stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED);        stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE);        stateMap.put(SupplicantState.INVALID, DetailedState.FAILED);    }    private SupplicantState mSupplicantState;    private String mBSSID;    private WifiSsid mWifiSsid;    private int mNetworkId;    /** @hide **/    public static final int INVALID_RSSI = -127;    /** @hide **/    public static final int MIN_RSSI = -126;    /** @hide **/    public static final int MAX_RSSI = 200;    /**     * Received Signal Strength Indicator     */    private int mRssi;    /**     * Link speed in Mbps     */    public static final String LINK_SPEED_UNITS = "Mbps";    private int mLinkSpeed;    /**     * Frequency in MHz     */    public static final String FREQUENCY_UNITS = "MHz";    private int mFrequency;    private InetAddress mIpAddress;    private String mMacAddress = DEFAULT_MAC_ADDRESS;    private boolean mEphemeral;    /**     * @hide     */    public long txBad;    /**     * @hide     */    public long txRetries;    /**     * @hide     */    public long txSuccess;    /**     * @hide     */    public long rxSuccess;    /**     * @hide     */    public double txBadRate;    /**     * @hide     */    public double txRetriesRate;    /**     * @hide     */    public double txSuccessRate;    /**     * @hide     */    public double rxSuccessRate;    /**     * @hide     */    public int badRssiCount;    /**     * @hide     */    public int linkStuckCount;    /**     * @hide     */    public int lowRssiCount;    /**     * @hide     */    public int score;    /**     * TODO: get actual timestamp and calculate true rates     * @hide     */    public void updatePacketRates(WifiLinkLayerStats stats) {        if (stats != null) {            long txgood = stats.txmpdu_be + stats.txmpdu_bk + stats.txmpdu_vi + stats.txmpdu_vo;            long txretries = stats.retries_be + stats.retries_bk                    + stats.retries_vi + stats.retries_vo;            long rxgood = stats.rxmpdu_be + stats.rxmpdu_bk + stats.rxmpdu_vi + stats.rxmpdu_vo;            long txbad = stats.lostmpdu_be + stats.lostmpdu_bk                    + stats.lostmpdu_vi + stats.lostmpdu_vo;            if (txBad <= txbad                    && txSuccess <= txgood                    && rxSuccess <= rxgood                    && txRetries <= txretries) {                txBadRate = (txBadRate * 0.5)                        + ((double) (txbad - txBad) * 0.5);                txSuccessRate = (txSuccessRate * 0.5)                        + ((double) (txgood - txSuccess) * 0.5);                rxSuccessRate = (rxSuccessRate * 0.5)                        + ((double) (rxgood - rxSuccess) * 0.5);                txRetriesRate = (txRetriesRate * 0.5)                        + ((double) (txretries - txRetries) * 0.5);            } else {                txBadRate = 0;                txSuccessRate = 0;                rxSuccessRate = 0;                txRetriesRate = 0;            }            txBad = txbad;            txSuccess = txgood;            rxSuccess = rxgood;            txRetries = txretries;        } else {            txBad = 0;            txSuccess = 0;            rxSuccess = 0;            txRetries = 0;            txBadRate = 0;            txSuccessRate = 0;            rxSuccessRate = 0;            txRetriesRate = 0;        }    }    /**     * This function is less powerful and used if the WifiLinkLayerStats API is not implemented     * at the Wifi HAL     * @hide     */    public void updatePacketRates(long txPackets, long rxPackets) {        //paranoia        txBad = 0;        txRetries = 0;        txBadRate = 0;        txRetriesRate = 0;        if (txSuccess <= txPackets && rxSuccess <= rxPackets) {            txSuccessRate = (txSuccessRate * 0.5)                    + ((double) (txPackets - txSuccess) * 0.5);            rxSuccessRate = (rxSuccessRate * 0.5)                    + ((double) (rxPackets - rxSuccess) * 0.5);        } else {            txBadRate = 0;            txRetriesRate = 0;        }        txSuccess = txPackets;        rxSuccess = rxPackets;    }        /**         * Flag indicating that AP has hinted that upstream connection is metered,         * and sensitive to heavy data transfers.         */    private boolean mMeteredHint;    /** @hide */    public WifiInfo() {        mWifiSsid = null;        mBSSID = null;        mNetworkId = -1;        mSupplicantState = SupplicantState.UNINITIALIZED;        mRssi = INVALID_RSSI;        mLinkSpeed = -1;        mFrequency = -1;    }    /** @hide */    public void reset() {        setInetAddress(null);        setBSSID(null);        setSSID(null);        setNetworkId(-1);        setRssi(INVALID_RSSI);        setLinkSpeed(-1);        setFrequency(-1);        setMeteredHint(false);        setEphemeral(false);        txBad = 0;        txSuccess = 0;        rxSuccess = 0;        txRetries = 0;        txBadRate = 0;        txSuccessRate = 0;        rxSuccessRate = 0;        txRetriesRate = 0;        lowRssiCount = 0;        badRssiCount = 0;        linkStuckCount = 0;        score = 0;    }    /**     * Copy constructor     * @hide     */    public WifiInfo(WifiInfo source) {        if (source != null) {            mSupplicantState = source.mSupplicantState;            mBSSID = source.mBSSID;            mWifiSsid = source.mWifiSsid;            mNetworkId = source.mNetworkId;            mRssi = source.mRssi;            mLinkSpeed = source.mLinkSpeed;            mFrequency = source.mFrequency;            mIpAddress = source.mIpAddress;            mMacAddress = source.mMacAddress;            mMeteredHint = source.mMeteredHint;            mEphemeral = source.mEphemeral;            txBad = source.txBad;            txRetries = source.txRetries;            txSuccess = source.txSuccess;            rxSuccess = source.rxSuccess;            txBadRate = source.txBadRate;            txRetriesRate = source.txRetriesRate;            txSuccessRate = source.txSuccessRate;            rxSuccessRate = source.rxSuccessRate;            score = source.score;            badRssiCount = source.badRssiCount;            lowRssiCount = source.lowRssiCount;            linkStuckCount = source.linkStuckCount;        }    }    /** @hide */    public void setSSID(WifiSsid wifiSsid) {        mWifiSsid = wifiSsid;    }    /**     * Returns the service set identifier (SSID) of the current 802.11 network.     * If the SSID can be decoded as UTF-8, it will be returned surrounded by double     * quotation marks. Otherwise, it is returned as a string of hex digits. The     * SSID may be <unknown ssid> if there is no network currently connected.     * @return the SSID     */    public String getSSID() {        if (mWifiSsid != null) {            String unicode = mWifiSsid.toString();            if (!TextUtils.isEmpty(unicode)) {                return "\"" + unicode + "\"";            } else {                return mWifiSsid.getHexString();            }        }        return WifiSsid.NONE;    }    /** @hide */    public WifiSsid getWifiSsid() {        return mWifiSsid;    }    /** @hide */    public void setBSSID(String BSSID) {        mBSSID = BSSID;    }    /**     * Return the basic service set identifier (BSSID) of the current access point.     * The BSSID may be {@code null} if there is no network currently connected.     * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX}     */    public String getBSSID() {        return mBSSID;    }    /**     * Returns the received signal strength indicator of the current 802.11     * network, in dBm.     *     * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into     * an absolute signal level which can be displayed to a user.     *     * @return the RSSI.     */    public int getRssi() {        return mRssi;    }    /** @hide */    public void setRssi(int rssi) {        if (rssi < INVALID_RSSI)            rssi = INVALID_RSSI;        if (rssi > MAX_RSSI)            rssi = MAX_RSSI;        mRssi = rssi;    }    /**     * Returns the current link speed in {@link #LINK_SPEED_UNITS}.     * @return the link speed.     * @see #LINK_SPEED_UNITS     */    public int getLinkSpeed() {        return mLinkSpeed;    }    /** @hide */    public void setLinkSpeed(int linkSpeed) {        this.mLinkSpeed = linkSpeed;    }    /**     * Returns the current frequency in {@link #FREQUENCY_UNITS}.     * @return the frequency.     * @see #FREQUENCY_UNITS     */    public int getFrequency() {        return mFrequency;    }    /** @hide */    public void setFrequency(int frequency) {        this.mFrequency = frequency;    }    /**     * @hide     * TODO: makes real freq boundaries     */    public boolean is24GHz() {        return ScanResult.is24GHz(mFrequency);    }    /**     * @hide     * TODO: makes real freq boundaries     */    public boolean is5GHz() {        return ScanResult.is5GHz(mFrequency);    }    /**     * Record the MAC address of the WLAN interface     * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form     * @hide     */    public void setMacAddress(String macAddress) {        this.mMacAddress = macAddress;    }    public String getMacAddress() {        return mMacAddress;    }

最后的这个String getMacAddress();这个方法 他返回了一个mMacAddress . 这个mMacAdress 在类的开头直接赋值
public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";    private String mMacAddress = DEFAULT_MAC_ADDRESS;所以他返回了的是一个 02:00:00 这样的一个值。
如果我们只需要在这个地方做一些修改。把他真正的mac地址返回去就可以了:

//add by vincent qq:514505874public String getMacAddress() {        if(mMacAddress.equals(DEFAULT_MAC_ADDRESS)){           return getWireMacAddr();        }else{      return mMacAddress;    }              }

getWriteMacAddr() 这个方法里面实现的就是把获取到的mac地址反馈回去。 实现的方法有很多种

例如直接通过CMD命令行获取mac地址:

private static final String ETH0_MAC_ADDR = "/sys/class/net/wlan0/address" ;  BufferedReader reader = new BufferedReader(new FileReader(ETH0_MAC_ADDR), 256);        try {            return reader.readLine();        } finally {            reader.close();        }
当然方法不止有这种。目的都是一样,只要能把 getMacAddress 这个旧api 的return 给返回一个真正的mac地址就可以了

欢迎沟通交流:QQ:514505874




阅读全文
0 0
原创粉丝点击