UWP中WifiScan到的SSID在顯示時候,中文顯示為亂碼的解決方法


  以前總是沒有經常寫技術博客的習慣, 這樣每次遇到問題, 甚至一些以前就遇到的問題, 還是要到處去找資料。另外,現在針對UWP編程方面的知識總結博客也不是那么豐富,對許多新的技術更是少得可憐, 有時候沒有辦法只能自己獨自摸索。

最近公司在做一個案子,是Win10的一個平板方面的應用, 里面涉及到網絡連接的問題, 先貼上wifi掃描部分的代碼:

 
         
 1         //接口
 2         //初始化Adapter
 3         public void Init()
 4         {
 5             WiFiAdapter.FindAllAdaptersAsync().AsTask().ContinueWith(antecedent =>
 6             {
 7                 if (antecedent.Result.Count >= 1)
 8                 {
 9                     _firstAdapter = antecedent.Result[0];
10                     DoCoMoSystem.WriteLog(_firstAdapter.NetworkAdapter.NetworkAdapterId.ToString());
11                 }
12                 else
13                 {
14                     OnError(this, "NoWiFiAdapter");
15                 }
16             });
17         }

1
//獲取所有連接 2 public async void GetAll() 3 { 4 if (_firstAdapter == null) return; 5 try 6 { 7 await _firstAdapter.ScanAsync(); 8 } 9 catch (Exception ex) 10 { 11 DoCoMoSystem.WriteLog("wifi scan exception..." + ex); 12 List<WiFiInfo> _list = new List<WiFiInfo>(); 13 14 if (OnGetAvailableNetworks != null) 15 OnGetAvailableNetworks(this, new AvailableNetworksEventArgs(_list)); 16 return; 17 } 18 19 List<WiFiInfo> list = await getWiFiInfoList(); 20 if (list == null) return; 21 22 if (OnGetAvailableNetworks != null) 23 OnGetAvailableNetworks(this, new AvailableNetworksEventArgs(list)); 24 25 }

 1         //獲取所有wifiinfo的列表
 2         private async Task<List<WiFiInfo>> getWiFiInfoList()
 3         {
 4             try
 5             {
 6                 string connectedSsid = await getConnectedSsid();
 7                 List<WiFiInfo> wifilist = new List<WiFiInfo>();
 8                 DoCoMoSystem.WriteLog("Connected WiFi is " + connectedSsid);
 9                 WiFiInfo connectedWifi = null;
10                 foreach (WiFiAvailableNetwork nt in _firstAdapter.NetworkReport.AvailableNetworks)
11                 {
12                     if (nt.Ssid == "")
13                     {
14                         DoCoMoSystem.WriteLog("Discover a empty string wifi...");
15                         continue;
16                     }
17                     WiFiInfo info = new WiFiInfo();
18                     info.BeaconInterval = nt.BeaconInterval;
19                     info.Bssid = nt.Bssid;
20                     info.ChannelCenterFrequencyInKilohertz = nt.ChannelCenterFrequencyInKilohertz;
21                     info.IsWiFiDirect = nt.IsWiFiDirect;
22                     info.PhyKind = nt.PhyKind;
23                     info.Ssid = nt.Ssid;
24                     info.SignalBars = nt.SignalBars;
25                     info.NetworkKind = nt.NetworkKind;
26                     info.NetworkRssiInDecibelMilliwatts = nt.NetworkRssiInDecibelMilliwatts;
27                     info.Uptime = nt.Uptime;
28                     if (nt.SecuritySettings.NetworkAuthenticationType == NetworkAuthenticationType.Open80211 &&
29                     nt.SecuritySettings.NetworkEncryptionType == NetworkEncryptionType.None)
30                     {
31                         info.IsSecurity = false;
32                     }
33                     else
34                     {
35                         info.IsSecurity = true;
36                     }
37                     if (connectedSsid != null && nt.Ssid == connectedSsid)
38                     {
39                         info.IsConnected = true;
40                         Ssid = connectedSsid;
41                         _state = WiFiStatus.CONNECTED;
42                         connectedWifi = info;
43                     }
44                     else
45                     {
46                         info.IsConnected = false;
47                         wifilist.Add(info);
48                     }
49                 }
50 
51                 wifilist.Sort(SortBySignalStrenth);
52                 if (connectedWifi != null)
53                     wifilist.Insert(0, connectedWifi);
54 
55                 return wifilist;
56             }
57             catch (Exception ex)
58             {
59                 if (OnError != null)
60                     OnError(this, "WIFIGETWIFIEXCEPTION");
61                 DoCoMoSystem.WriteLog("DCMWiFi.getWiFiInfoList exception." + ex.Message);
62             }
63             return null;
64         }

上面加背景部分的代碼是獲取wifi AP的名稱, 如果直接獲取並在界面上去顯示的話,如果AP名稱中包含中文名字的話, 會顯示亂碼, 一開始接到這個問題反饋的時候,也認為這個肯定是編碼方面的問題嘛, 應該不難解決, 以前即使沒有認真對待這個問題, 但是應該也是遇到過的, 解決起來應該不成問題, 可悲催的是, 網上搜了一大圈, 居然都沒有正確的解決方法, 要不就是方法無法在UWP上使用, 這么一個問題居然困擾了我一整天, 仍然解決不了。 

后來還是將抓取到的亂碼名稱copy到notepad++中, 然后用不同的編碼格式去轉換, 才發現, 原始的SSID編碼格式是ANSI, 而如果用UTF-8去重新編碼的話, 中文名稱也就正常顯示了, Okay,至少知道解決方法的算法應該是什么了: 如何將ANSI編碼格式轉換為UTF-8編碼格式。

System.Text.Encoding類用於編碼轉換,查詢資料知道ANSI編碼格式,對應Encoding.Default編碼格式, 但是這個枚舉類型在UWP中不可用, 但是有提供一個方法Encoding.GetEncoding(int codepage)用於手動添加編碼格式(語言編碼表可以參見鏈接:https://msdn.microsoft.com/zh-cn/library/86hf4sb8(v=vs.80).aspx), 但其實Encoding.Default對應的值是0, 所以采用方法Encoding.GetEncoding(0)來獲取ANSI的編碼格式。 

所以編碼轉換方法寫成:

 1         /// <summary>
 2         /// 編碼轉換,解決SSID亂碼問題
 3         /// </summary>
 4         /// <param name="ssid_src"></param>
 5         /// <returns></returns>
 6         private string convertSSID(string ssid_src)
 7         {
 8             var encoding = Encoding.GetEncoding(0);
 9             var bytes = encoding.GetBytes(ssid_src);
10             string ssid_dst = Encoding.UTF8.GetString(bytes);
11             return ssid_dst;
12         }

但是在運行的時候會報錯:

按照提示, 表示要新注冊encoding類型的話, 需要乃至Encoding.RegisterProvider這個方法, 在這篇文章中(http://www.cnblogs.com/artech/p/encoding-registeration-4-net-core.html)查詢到這個方法的調用方法:

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

這樣, 編碼轉換方法即改為:

 1         /// <summary>
 2         /// 編碼轉換,解決SSID亂碼問題
 3         /// </summary>
 4         /// <param name="ssid_src"></param>
 5         /// <returns></returns>
 6         private string convertSSID(string ssid_src)
 7         {
 8             Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
 9             var encoding = Encoding.GetEncoding(0);
10             var bytes = encoding.GetBytes(ssid_src);
11             string ssid_dst = Encoding.UTF8.GetString(bytes);
12             return ssid_dst;
13         }

回到上面的private async Task<List<WiFiInfo>> getWiFiInfoList()方法, 在保存SSID處改為:

                    info.Ssid = convertSSID(nt.Ssid);

大功告成!實測結果:

 

P.S.: 我寫的Demo程式,在運行的時候還遇到一個問題, 就是如果是運行在Win10的NB上 時候,並且wifi名稱用日文(沒有試過其他語言了)命名的時候, 程式顯示的是一串類似於MD5碼一樣的字符, 此時無論如何轉換也沒有辦法正常顯示日文出來, 不是很了解原因, 但是如果是運行在我們公司在做那款機器上, 卻是正常顯示日文wifi名稱的, 這個問題暫時沒有去解(因為主要目的是解決在機器上的運行結果問題啊- -), 如果有看到的大神可以提供一下建議。

P.S.: 不是太經常寫, 如果有看得不舒服的,歡迎指正, 以后的博客會改進, 謝謝!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM