小编简单介绍如何通过调用android API来获取wifi服务(
非常感谢作者安晓辉发布了qt android 核心编程这本书,让我两天搞懂了很多在qt中开发安卓的要领,现在跟大家分享下!至于还没知道
怎么配置qt android换将的开发者,极力推荐先去看看qt android 核心编程这本书(哈哈,一知道要出这本书, 还没出版的时候我天天看着京东
有货了没!)
上代码!
工程源码(这些都是大二大三时候造的,代码可能有点烂)
ExtendsQtWithJava.java

package an.qt.extendsQtWithJava;import android.app.PendingIntent;
import android.widget.Toast;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.location.LocationManager;
import android.location.Criteria;
import android.provider.Settings;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationProvider;
import java.lang.ClassLoader;
import dalvik.system.DexClassLoader;
import java.lang.reflect.Field;
import android.os.Bundle;
import android.os.Environment;
import java.io.File;//tommegoimport java.util.List;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import java.io.IOException;
import java.lang.Exception;
import java.lang.Throwable;
import android.net.DhcpInfo;
import android.content.Context;//屏幕像素密度
import android.util.DisplayMetrics;
//tommegopublic class ExtendsQtWithJava extends org.qtproject.qt5.android.bindings.QtActivity
{private static ExtendsQtWithJava m_instance;/***************************tommego*********************************************************************************//***************************tommego*********************************************************************************/public static WifiInfo currentWifiInfo;//当前所连接的wifipublic static List<ScanResult> wifiList;// wifi列表public static List<WifiConfiguration> wifiConList;// wifi 已成功连接过的配置列表public static int wifiIndex;//从scanResult 得到的wifi列表进行记录位置public static  String[] str;//。。。。。//手机连接wifi 后得到的动态ippublic static DhcpInfo hostDhcpInfo;/***************************tommego*********************************************************************************//***************************tommego*********************************************************************************/public ExtendsQtWithJava(){m_instance = this;}                                   //实例化单例对象/***************************tommego*********************************************************************************//***************************tommego*********************************************************************************///open wifipublic static void openWifi(){WifiManager conMan = (WifiManager) m_instance.getSystemService(Context.WIFI_SERVICE);if(!conMan.isWifiEnabled()){conMan.setWifiEnabled(true);}}//close wifipublic static void closeWifi(){WifiManager conMan = (WifiManager) m_instance.getSystemService(Context.WIFI_SERVICE);if(conMan.isWifiEnabled()){conMan.setWifiEnabled(false);}}//scan wifipublic static void scanWifi(){WifiManager conMan = (WifiManager) m_instance.getSystemService(Context.WIFI_SERVICE);conMan.startScan();// 获取扫描结果wifiList = conMan.getScanResults();}//get wifi infopublic static int getWifiCount(){return wifiList.size();}public static String getWifiSSID(int index){if(index>=0&&index<wifiList.size()){return wifiList.get(index).SSID;}else{return "";}}public static int getWifiLevel(int index){if(index>=0&&index<wifiList.size()){return wifiList.get(index).level;}else{return 0;}}public static int getWifiFrequency(int index){if(index>=0&&index<wifiList.size()){return wifiList.get(index).frequency;}else{return 0;}}public static String getWifiBSSID(int index){if(index>=0&&index<wifiList.size()){return wifiList.get(index).BSSID;}else{return "";}}//加密方式判断public static String getWifiKeyType(int index){if (wifiList.get(index).capabilities.contains("WEP")) {return "WEP";} else if (wifiList.get(index).capabilities.contains("PSK")) {return "PSK";} else if (wifiList.get(index).capabilities.contains("EAP")) {return "EAP";}return "无";}//get current connected wifi infopublic static String getCurrentWifiSSID(){WifiManager conMan = (WifiManager) m_instance.getSystemService(Context.WIFI_SERVICE);currentWifiInfo = conMan.getConnectionInfo();return currentWifiInfo.getSSID();}//get current ip addresspublic static String getCurrentWifiIPAddress(){WifiManager conMan = (WifiManager) m_instance.getSystemService(Context.WIFI_SERVICE);currentWifiInfo = conMan.getConnectionInfo();return WifiUtil.intToIp(currentWifiInfo.getIpAddress());}//还是路由派来的IP,啊啊啊啊(…*……*…)public static String getHostIPAddress(){WifiManager conMan = (WifiManager) m_instance.getSystemService(Context.WIFI_SERVICE);hostDhcpInfo = conMan.getDhcpInfo();return WifiUtil.intToIp(hostDhcpInfo.serverAddress);}//get current network idpublic static int getCurrentNetworkId(){WifiManager conMan = (WifiManager) m_instance.getSystemService(Context.WIFI_SERVICE);currentWifiInfo = conMan.getConnectionInfo();return currentWifiInfo.getNetworkId();}//get current connected wifi info//get wifi connect statepublic static int networkState(){WifiManager conMan = (WifiManager) m_instance.getSystemService(Context.WIFI_SERVICE);return conMan.isWifiEnabled()? 1 : 0;}//连接到新设备public static void connectDevice(String ssid,String passwd){
//        WifiConfiguration wc = new WifiConfiguration();
//        wc.SSID = "\""+ssid+"\"";
//        wc.preSharedKey = "\""+passwd+"\"";//        wc.hiddenSSID = true;
//        wc.status = WifiConfiguration.Status.ENABLED;
//        wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
//        wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
//        wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
//        wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
//        wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
//        wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
//        wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);}//生成一个网络配置public WifiConfiguration CreateWifiInfo(ScanResult scanresult,String Password){WifiConfiguration wc = new WifiConfiguration();wc.SSID = "\""+scanresult.SSID+"\"";      //<span style="color: rgb(255, 0, 0); ">这个地方一定要注意了。旁边的“是不能够省略的。密码的地方也一样。</span>wc.preSharedKey = "\""+Password+"\"";      //该热点的密码wc.hiddenSSID = true;wc.status = WifiConfiguration.Status.ENABLED;wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);return wc;}//无密码public WifiConfiguration CreateWifiInfoWithoutPasswd(ScanResult scanresult){WifiConfiguration wc = new WifiConfiguration();wc.SSID = "\""+scanresult.SSID+"\"";      //<span style="color: rgb(255, 0, 0); ">这个地方一定要注意了。旁边的“是不能够省略的。密码的地方也一样。</span>
//        wc.preSharedKey = "\""+Password+"\"";      //该热点的密码wc.hiddenSSID = true;wc.status = WifiConfiguration.Status.ENABLED;wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);return wc;}//根据网络配置连接wifipublic static int connectToWifi(int scanresultId,String Password){WifiManager conMan = (WifiManager) m_instance.getSystemService(Context.WIFI_SERVICE);int networkId = conMan.addNetwork(m_instance.CreateWifiInfo(wifiList.get(scanresultId),Password));if(networkId != -1){conMan.enableNetwork(networkId, false);conMan.saveConfiguration();return 1;//success}return 0;//falure}//无密码public static int connectToWifiWithoutPasswd(int scanresultId){WifiManager conMan = (WifiManager) m_instance.getSystemService(Context.WIFI_SERVICE);int networkId = conMan.addNetwork(m_instance.CreateWifiInfoWithoutPasswd(wifiList.get(scanresultId)));if(networkId != -1){conMan.enableNetwork(networkId, false);conMan.saveConfiguration();return 1;//success}return 0;//falure}//获取屏幕像素密度public static double getDentisy(){DisplayMetrics metrics=new DisplayMetrics();m_instance.getWindowManager().getDefaultDisplay().getMetrics(metrics);return metrics.density;}/***************************tommego*********************************************************************************//***************************tommego*********************************************************************************/
}

WifiUtil.java //一个将IP二进制转换我们能理解的地址的类

package an.qt.extendsQtWithJava;
import java.util.List;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
public class WifiUtil
{public static WifiConfiguration createWifiInfo(String SSID,String Password, int Type, WifiManager wifiManager){WifiConfiguration config = new WifiConfiguration();config.allowedAuthAlgorithms.clear();config.allowedGroupCiphers.clear();config.allowedKeyManagement.clear();config.allowedPairwiseCiphers.clear();config.allowedProtocols.clear();config.SSID = "\"" + SSID + "\"";WifiConfiguration tempConfig = isExsits(SSID, wifiManager);if (tempConfig != null) {wifiManager.removeNetwork(tempConfig.networkId);}if (Type == 1) // WIFICIPHER_NOPASS{config.wepKeys[0] = "";config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);config.wepTxKeyIndex = 0;}if (Type == 2) // WIFICIPHER_WEP{config.hiddenSSID = true;config.wepKeys[0] = "\"" + Password + "\"";config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);config.wepTxKeyIndex = 0;}if (Type == 3) // WIFICIPHER_WPA{config.preSharedKey = "\"" + Password + "\"";config.hiddenSSID = true;config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);// config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);config.status = WifiConfiguration.Status.ENABLED;}return config;}//判断wifi是否存在private static WifiConfiguration isExsits(String SSID,WifiManager wifiManager){List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();for (WifiConfiguration existingConfig : existingConfigs) {if (existingConfig.SSID.equals("\"" + SSID + "\"")) {return existingConfig;}}return null;}//转换IP地址public static String intToIp(int i){return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF)+ "." + ((i >> 24) & 0xFF);}
}

这个是java端实现操作wifi的类,接下来是c++通过jni调用java接口的实现
wifimanager.h

#ifndef WIFIMANAGER_H
#define WIFIMANAGER_H#include <QObject>
#include <QAndroidJniObject>
#include <QList>
#include <QString>struct WifiInfo{int level;QString SSID;QString BSSID;QString keytype;
};class WifiManager : public QObject
{Q_OBJECT
public:explicit WifiManager(QObject *parent = 0);~WifiManager();//wifi processQ_INVOKABLE bool isWifiEnable();Q_INVOKABLE void openWifi();Q_INVOKABLE void closeWifi();Q_INVOKABLE void scanWifi();Q_INVOKABLE int getWifiListCount();Q_INVOKABLE QString getWifiSSID(int index);Q_INVOKABLE QString getWifiBSSID(int index);Q_INVOKABLE int getWifiLevel(int index);Q_INVOKABLE QString getKeyType(int index);//获取当前连接的wifi信息Q_INVOKABLE QString getConntectedWifiSSID();Q_INVOKABLE QString getConnectedWifiAddress();//连接到wifiQ_INVOKABLE void connectToWifi(int id,QString passwd);Q_INVOKABLE void connectToWifiWithoutPasswd(int id);//多媒体音量控制Q_INVOKABLE int getMaxVolumnStream();Q_INVOKABLE int getCurrentVolumnStream();Q_INVOKABLE void setVolumnStream(int a);//获取屏幕像素密度Q_INVOKABLE double getDentisy();//user processQ_INVOKABLE void refreshWifiList();Q_INVOKABLE int  wifiCount();Q_INVOKABLE int  wifiLevel(int i);Q_INVOKABLE QString wifiSSID(int i);Q_INVOKABLE QString wifiBSSID(int i);Q_INVOKABLE QString wifiKeyType(int i);signals:public slots:
private:QList<WifiInfo> wifiList;};#endif // WIFIMANAGER_H

wifimanager.cpp

#include "wifimanager.h"
#include <QDebug>
#include <math.h>
#include "jni.h"WifiManager::WifiManager(QObject *parent) : QObject(parent)
{}WifiManager::~WifiManager()
{}/***********************************wifi cability ********************/
bool WifiManager::isWifiEnable(){jint state =QAndroidJniObject::callStaticMethod<jint>("an/qt/extendsQtWithJava/ExtendsQtWithJava","networkState");return state==1?true:false;
}void WifiManager::openWifi(){QAndroidJniObject::callStaticMethod<void>("an/qt/extendsQtWithJava/ExtendsQtWithJava","openWifi");
}void WifiManager::closeWifi(){QAndroidJniObject::callStaticMethod<void>("an/qt/extendsQtWithJava/ExtendsQtWithJava","closeWifi");
}void WifiManager::scanWifi(){QAndroidJniObject::callStaticMethod<void>("an/qt/extendsQtWithJava/ExtendsQtWithJava","scanWifi");
}int WifiManager::getWifiListCount(){jint count=QAndroidJniObject::callStaticMethod<jint>("an/qt/extendsQtWithJava/ExtendsQtWithJava","getWifiCount");return count;
}QString WifiManager::getWifiSSID(int index){QAndroidJniObject str=QAndroidJniObject::callStaticObjectMethod("an/qt/extendsQtWithJava/ExtendsQtWithJava","getWifiSSID","(I)Ljava/lang/String;",index);return str.toString();
}QString WifiManager::getWifiBSSID(int index){QAndroidJniObject str=QAndroidJniObject::callStaticObjectMethod("an/qt/extendsQtWithJava/ExtendsQtWithJava","getWifiBSSID","(I)Ljava/lang/String;",index);return str.toString();}int WifiManager::getWifiLevel(int index){int a= QAndroidJniObject::callStaticMethod<int>("an/qt/extendsQtWithJava/ExtendsQtWithJava","getWifiLevel","(I)I",index);qDebug()<<"wifi level: "<<a;if(abs(a)>80){return 1;}else if(abs(a)>50&&abs(a)<=80){return 2;}else if(abs(a)<=50){return 3;}
}QString WifiManager::getKeyType(int index){QAndroidJniObject str=QAndroidJniObject::callStaticObjectMethod("an/qt/extendsQtWithJava/ExtendsQtWithJava","getWifiKeyType","(I)Ljava/lang/String;",index);return str.toString();
}//获取当前连接的wifi信息
QString WifiManager::getConntectedWifiSSID(){QAndroidJniObject str=QAndroidJniObject::callStaticObjectMethod("an/qt/extendsQtWithJava/ExtendsQtWithJava","getCurrentWifiSSID","()Ljava/lang/String;");return str.toString();}QString WifiManager::getConnectedWifiAddress(){QAndroidJniObject str=QAndroidJniObject::callStaticObjectMethod("an/qt/extendsQtWithJava/ExtendsQtWithJava","getHostIPAddress","()Ljava/lang/String;");return str.toString();}//连接到wifi
void WifiManager::connectToWifi(int id,QString passwd){QAndroidJniObject str=QAndroidJniObject::fromString(passwd);jint a=QAndroidJniObject::callStaticMethod<jint>("an/qt/extendsQtWithJava/ExtendsQtWithJava","connectToWifi","(ILjava/lang/String;)I",id,str.object<jstring>());qDebug()<<"connect to wifi :"<<a;
}
void WifiManager::connectToWifiWithoutPasswd(int id){jint a=QAndroidJniObject::callStaticMethod<jint>("an/qt/extendsQtWithJava/ExtendsQtWithJava","connectToWifiWithoutPasswd","(I)I",id);qDebug()<<"connect to wifi :"<<a;
}/***********************************wifi cability ********************//***********************************多媒体音量控制********************/int WifiManager::getMaxVolumnStream(){return QAndroidJniObject::callStaticMethod<int>("an/qt/extendsQtWithJava/ExtendsQtWithJava","getMaxVolumnStream","()I");
}int WifiManager::getCurrentVolumnStream(){return QAndroidJniObject::callStaticMethod<int>("an/qt/extendsQtWithJava/ExtendsQtWithJava","getCurrentVolumnStream","()I");
}void WifiManager::setVolumnStream(int a){QAndroidJniObject::callStaticMethod<void>("an/qt/extendsQtWithJava/ExtendsQtWithJava","setVolumnStream","(I)V",a);
}/***********************************多媒体音量控制********************///获取屏幕像素密度
double WifiManager::getDentisy(){return QAndroidJniObject::callStaticMethod<double>("an/qt/extendsQtWithJava/ExtendsQtWithJava","getDentisy","()D");
}/***********************************user functionds*************************/
void WifiManager::refreshWifiList(){wifiList.clear();scanWifi();int count=getWifiListCount();for(int a=0;a<count;a++){WifiInfo info;info.SSID=getWifiSSID(a);info.BSSID=getWifiBSSID(a);info.level=getWifiLevel(a);info.keytype=getKeyType(a);wifiList.append(info);}
}int  WifiManager::wifiCount(){return wifiList.count();
}int  WifiManager::wifiLevel(int i){return wifiList.at(i).level;
}QString WifiManager::wifiSSID(int i){return wifiList.at(i).SSID;
}QString WifiManager::wifiBSSID(int i){return wifiList.at(i).BSSID;
}QString WifiManager::wifiKeyType(int i){return wifiList.at(i).keytype;
}
/***********************************user functionds*************************/

效果截图:

qt android 开发之wifi开发篇相关推荐

  1. Android开发之WIFI与网络连接处理

    网络连接处理 在说WiFi之前,先来说说网络连接处理. 在Android开发过程中,对于一个需要连接网络的Android设备,对设备的网络状态检测是很有必要的!有很多的App都需要连接网络.判断设备是 ...

  2. Android开发之SDK开发获取资源id报错的问题

    我们在开发SDK的时候有时候需要兼容Eclipse版本和AS版本,AS版本就不说了没多大问题,主要是Eclipse版本会有问题.当开发之使用Eclipse开发的时候接入jar包(AS打包成aar,解压 ...

  3. Android开发之Is Library篇

    一.生活场景描述 由于公司有一个项目开发的时间比较长,项目里堆砌的代码也比较多,并且有些功能在给不同客户发布的时候有些功能还不需要,这样功能模块分离就很有必要了. 所以,Library就被推到了前台, ...

  4. Android开发之 Wifi扫描分析

    使用 开始wifi扫描的代码很简单: val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager v ...

  5. Android开发之Fmod开发引擎库-----变声

    最近接到一个项目需求,大概是围绕***变声***这个功能展开的. 我从来没有写过这样的项目,抱着好奇的心态百度了一番,找到了一个是为游戏开发者准备的革命性音频引擎------FMOD开发引擎库. 1. ...

  6. Android开发之ApiCloud模块开发之模块引用第三方库的问题

    因为现在第三方库比较多,所以很多人为了快速开发导致库用烂大街了,但是在模块开发中本人不建议使用第三方库的依赖会有很多问题,要么是资源图片找不到,要么是布局找不到啥的,但是有的需求只有第三方库怎么办呢? ...

  7. 新浪微博Android客户端开发之OAuth认证篇

    新浪微博客户端开发之OAuth认证篇 2013年7月29日新浪微博客户端开发 OAuth2.0授权机制我在这里就不浪费口舌了,有很多大牛都发表过相关的文章解释OAuth2.0认证的流程,我就随便找了一 ...

  8. Linux嵌入式系统开发之Led开发——应用篇(一)

    与Linux嵌入式系统开发之Led开发--驱动篇(一),对于的应用篇 看看咱们的开发板,有四个led灯,对吧,这次就是向办法用程序来点亮它,请看下边的代码: #include <stdlib.h ...

  9. android 视频开发sd卡,Android开发之SD卡文件操作分析

    本文实例讲述了Android开发之SD卡文件操作.分享给大家供大家参考,具体如下: 前面的文章中写过直接操作手机自带存储器的程序,这次就接着上次文章协议下对sd卡的文件操作.与自带存储不同的是使用sd ...

最新文章

  1. iOS App Launch Option
  2. spring logback mysql_logback 日志输出格式
  3. 万达放弃A股上市,数据揭秘王思聪投资为何频繁跳水?
  4. vhd 镜像 备份Linux,差分VHD 系统秒备份、秒还原教程 完胜GHOST
  5. C#程序开机启动与获取程序启动路径
  6. Mob统计分析游戏类App详细埋点需求
  7. 云图说|初识云数据库GaussDB(for Cassandra)
  8. 再见了,mover。当打之年,感恩相遇,感恩联汇,感恩一切。
  9. CSS:布局——圣杯布局和双飞翼布局
  10. matlab如何画出来地球,matlab绘制地球
  11. 电力系统同步发电机励磁系统的建模与仿真
  12. graphpad饼状图_应用 Graphpad 统计作图,助你写文章事半功倍
  13. 基于 DirectShow 实现 SourceFilter 常见问题分析
  14. 小米笔记本Air 13.3 i5-8250U macOS黑苹果efi引导文件
  15. 8个最好用的H5页面制作工具
  16. ISCC2022wp
  17. 详解Nginx的核心原理
  18. 华为模拟器ENSP router设备上display ip routing-table详解
  19. 我在公司彻夜撸码,老板天天开X6夜店蹦迪,到头来工资还拖欠
  20. GPS定位系统(二)——Android端

热门文章

  1. 谷歌地图的全球森林监察系统,揭秘中国雾霾的惊天秘密!
  2. 5G、物联网和AI结合的究极形态是什么?一文看尽智能连接在5大领域的12个典型案例!...
  3. 行业变革的镜子:2018年融资最多的24家美国创业公司
  4. 李德毅:“反用驾驶脑”测认知能力,谁说酒驾一定违规?
  5. 硅谷人眼中的2018年十大前沿科技预测
  6. 中科院自动化所介绍深度强化学习进展:从AlphaGo到AlphaGo Zero
  7. 神经网络中的「注意力」是什么?怎么用?
  8. “技术崇拜”与“技术恐惧”都会阻碍 AI 创新,“技术节制”才是正道
  9. 再见,Windows 7!盘点 2020 影响开发者的十大事件!
  10. c++ primer plus 学习笔记