在 Oreo (8.1.0) 上没有获得正确的 Wifi SSID。它显示 <unknown ssid> 虽然它已连接到具有 SSID 的 wifi

On Oreo (8.1.0) not getting the correct Wifi SSID. It's showing <unknown ssid> though it is connected to a wifi with SSID

我需要检查 android 上当前连接的 wifi SSID。我分别使用 Oreo 8.1.0 和 Oreo 8.0 检查了诺基亚 6 和 OnePlus 5。其他 OS 版本不同的手机可以正常使用此代码。我的代码有什么问题吗?

private WifiInfo wifiInfo;
private String ssid = "";
private WifiManager wifiManager;

private boolean getWifiStatus() {
    wifiManager= (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    wifiInfo = wifiManager.getConnectionInfo();
    ssid = "";
    ssid = wifiInfo.getSSID();
    ConnectivityManager cm =
            (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean isWiFi = false;
    if(activeNetwork != null){
        isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
    }

    Log.d(TAG, "getWifiStatus: " + ssid);
    if(ssid.contains("TripleMZim") && wifiManager.isWifiEnabled() && isWiFi ){
        return true;
    }
    else{
        return false;
    }
}

清单文件中的权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>

Oreo 8.1+ 设备需要粗略位置运行时权限以及打开位置服务才能检索连接的 SSID,因为它可以推断用户位置。

更多信息是available here

this

有关

在 Android Oreo 中,您可以使用 ConnectivityManager 来了解您的 wifi SSID。

权限

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

获取SSID的代码

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null && info.isConnected()) {
    String ssid = info.getExtraInfo();
    Log.d(TAG, "WiFi SSID: " + ssid);
}

这已在 Android Oreo 8.1.0 中测试。您将获得用双引号括起来的 SSID。

如果您在尝试 Yaswant Narayan 和 behelit 答案后仍遇到问题,请确保在尝试获取 SSID 时已在设备中启用 Location/GPS。即使你在Android Oreo 及以上设备上获得了相关权限,如果Location/GPS 被用户关闭,那么你会从这些设备上获得。

在android.

中获取WIFI信息(如SSID)有多种方法

其中一些已在此处列出,例如 WifiManager 服务。

但对于 OP 问题:

Is there anything wrong with my code?

不,问题不在你的代码中。 出现意外行为的主要原因是最近 android 版本的安全补丁。

在补丁(或任何未获得更新的设备)之前,黑客可以窃取通过 wifi 信息泄露的敏感信息。

例如,黑客可以获得设备地理位置,该位置只能通过 Dangerous Permission LOCATION, that should be requested at runtime and can be revoked at any moment. But in the other hand - the WifiInfo is accessible only with the Normal Permission android.permission.ACCESS_WIFI_STATE 访问,该权限在安装时授予且无法撤销。 这样,黑客就可以绕过权限机制,仅使用普通权限访问危险权限的数据。

此问题已由 CVE-2018-9489 报告和跟踪,您可以在此处阅读更多相关信息:Sensitive information expose via WIFI

所以你遇到这些问题的原因是因为现在 android 阻止了敏感的 wifi 信息,除非应用程序持有 ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION.

因此,如果您明确请求这些权限(并且用户允许),您的代码应该可以正常工作。

例如:

清单

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Activity

private static final int LOCATION = 1;
protected void onStart() {
   super.onStart();
   //Assume you want to read the SSID when the activity is started
   tryToReadSSID();
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if(grantResults[0] == PackageManager.PERMISSION_GRANTED && requestCode == LOCATION){
        //User allowed the location and you can read it now
        tryToReadSSID();
    }
}

private void tryToReadSSID() {
    //If requested permission isn't Granted yet
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        //Request permission from user
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION);
    }else{//Permission already granted 
        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        if(wifiInfo.getSupplicantState() == SupplicantState.COMPLETED){
            String ssid = wifiInfo.getSSID();//Here you can access your SSID
            System.out.println(ssid);
        }
    }
}

您需要在清单中请求权限:

 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

并在您的 activity 中请求它:

    private void grantPermm()
{

    try
    {
        if (ContextCompat.checkSelfPermission(MainScreenActivity.this,
                  Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)

        {

        }
        else
        {

            ActivityCompat.requestPermissions(MainScreenActivity.this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    101);
        }

    }
    catch (Exception xx){}

}

然后使用这个函数:

    public  static String  getWifiName(Context context)
{
    String result="";
    try {
        WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        if (manager.isWifiEnabled())
        {
            WifiInfo wifiInfo = manager.getConnectionInfo();
            if (wifiInfo != null)
            {
                NetworkInfo.DetailedState state = WifiInfo.getDetailedStateOf(wifiInfo.getSupplicantState());
                if (state == NetworkInfo.DetailedState.CONNECTED || state == NetworkInfo.DetailedState.OBTAINING_IPADDR)
                {
                    result = wifiInfo.getSSID();
                    if(result.equalsIgnoreCase("<unknown ssid>"))
                    {
                        Toast.makeText(context,"You are connected to mobile data", Toast.LENGTH_SHORT).show();
                        result="";
                    }

                    return result;
                }
                else
                {
                    Toast.makeText(context,"WIFI not connected", Toast.LENGTH_SHORT).show();
                    return "";
                }
            }
            else
            {
                Toast.makeText(context,"No WIFI Information", Toast.LENGTH_SHORT).show();
                return "";
            }
        }
        else
        {
            Toast.makeText(context,"WIFI not enabled", Toast.LENGTH_SHORT).show();
            return "";
        }
    }
    catch (Exception xx)
    {
        Toast.makeText(context, xx.getMessage().toString(), Toast.LENGTH_SHORT).show();
        return "";
    }
}

您需要请求读取phone状态的运行时权限。这是为了更好的安全性。

代码如下:-

    TelephonyManager telephonyManager = (TelephonyManager) getContext()
            .getSystemService(Context.TELEPHONY_SERVICE);

    String IMEI ="";

    if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
       ActivityCompat.requestPermissions(getActivity(),
               new String[]{Manifest.permission.READ_PHONE_STATE},
               123);

    }
    int permission = ContextCompat.checkSelfPermission(getContext(),
            Manifest.permission.READ_PHONE_STATE);
    if(permission == PackageManager.PERMISSION_GRANTED){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            IMEI = telephonyManager.getImei();
        }
        else{
            IMEI = telephonyManager.getDeviceId();
        }
    }

如果您的目标是 API 29 (Android 10),那么请求的位置权限现在必须针对 ACCESS_FINE_LOCATION,而不仅仅是 ACCESS_COARSE_LOCATION。上面的大部分示例代码都很好,但是文本中的一些答案可能会产生误导。

https://developer.android.com/about/versions/10/privacy/changes