【问题标题】: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在 Oreo (8.1.0) 上没有获得正确的 Wifi SSID。它显示 <unknown ssid> 虽然它已连接到具有 SSID 的 wifi
【发布时间】:2018-10-03 06:45:22
【问题描述】:

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

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;
    }
}

Manifest 文件中的权限:

<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"/>

【问题讨论】:

    标签: android wifi android-8.0-oreo ssid


    【解决方案1】:

    在android中获取WIFI信息(如SSID)有多种方式。

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

    但对于 OP 问题:

    我的代码有什么问题吗?

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

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

    例如,黑客可以获取设备地理位置,这应该只能通过Dangerous Permission LOCATION 访问,应该在运行时请求并且可以随时撤销。但另一方面 - WifiInfo 只能通过在安装时授予的 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"/>
    

    活动

    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);
            }
        }
    }
    

    【讨论】:

    • 问题已解决。谢谢你的解释。
    • @bh_earth0 检查了android 8.1 和最新的android 10 (API 29) -> 它完美运行,所以我猜你还有其他问题。如果您仍然无法解决它,请为它打开一个新的专用问题,并提供所有详细信息(源代码、错误、您尝试过什么等...)
    【解决方案2】:

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

    更多信息是available here

    这与this有关

    【讨论】:

      【解决方案3】:

      在 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。

      【讨论】:

      • @AmitGarg 它不起作用,因为使用 Pie,您需要启用 GPS 并且应用程序具有“位置”权限,然后您才会看到 SSID。否则,您将在日志中看到“”。
      • @WahibUlHaq 在启用 GPS 并设置位置权限时,它不适用于 Android Pie 9.0 事件。在 Pixel XL(第一代)上测试
      • 我在 Pixel (9.0) 上也进行了测试,效果很好。您可以使用 adb 命令重新确认您的 wifi 状态,还取决于您何时调用此代码。例如,在断开连接状态下,即使启用了 GPS,我也看不到 wifi ssid。
      • 这里适用于 Android 9 (Pixel XL),但不适用于 OnePlus Android 8。(提供位置访问权限)
      【解决方案4】:

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

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

      并在您的活动中请求它:

          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 "";
          }
      }
      

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            【解决方案7】:

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

            代码如下:-

                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();
                    }
                }
            

            【讨论】:

              猜你喜欢
              • 2021-02-05
              • 2014-02-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-11-30
              • 2014-10-06
              相关资源
              最近更新 更多