我想创建一个像shareit这样的文件共享应用程序,但我真的很困惑shareit如何发现附近的设备。
单击“接收”按钮时,shareit会在接收方创建热点,而发送方无需连接到热点即可显示接收方名称。怎么可能?
如果shareit直接使用Wi-Fi,那么创建热点的重点是什么?
并且要使用网络服务发现(NSD)服务器和客户端应该在同一网络上,所以我认为shareit正在使用其他东西
如果有人能解释这种共享概念,那将非常有帮助。
我终于找到了答案! SHAREit使用WiFi SSID识别附近的应用用户。 SSID由两部分组成。 BAHD-bXViYQ在哪里'B'代表ANDROID DEVICE和AHD代表用户图标。第二部分是在Base64中编码的用户名。在这个例子中我的名字是muba。我希望这个答案有助于节省一些时间。
您看过了吗:Using Wi-Fi P2P for Service Discovery我没有亲自使用它,但是给出了描述,它可能会提供您正在寻找的内容......
好吧,我已经找到了如何从一个共享应用程序启用hotspot
,并找到该共享应用程序启用的另一个可用的WiFi列表。就像shareIt receiver
启用wifi热点和sender discovers
可用的receivers
列表。首先,你必须使用WifiManager
扫描所有可用的wifi网络
public void startScan(){
mWifiManager.startScan();
mScanResultList = mWifiManager.getScanResults();
mWifiConfigurations = mWifiManager.getConfiguredNetworks();
}
现在将此mScanResultList
传递给根据您的要求查找网络的方法。
public static List<ScanResult> filterWithNoPassword(List<ScanResult> scanResultList){
if(scanResultList == null || scanResultList.size() == 0){
return scanResultList;
}
List<ScanResult> resultList = new ArrayList<>();
for(ScanResult scanResult : scanResultList){
if(scanResult.capabilities != null && scanResult.capabilities.equals(NO_PASSWORD) || scanResult.capabilities != null && scanResult.capabilities.equals(NO_PASSWORD_WPS)){
resultList.add(scanResult);
}
}
return resultList;
}
现在将resultList
传递给arraylist适配器以显示列表中的网络。内部适配器的convertView
方法只是将dataList传递给扫描器以获取网络的ssid和mac地址
@Override
public View convertView(int position, View convertView) {
ScanResultHolder viewHolder = null;
if(convertView == null){
convertView = View.inflate(getContext(), R.layout.item_wifi_scan_result, null);
viewHolder = new ScanResultHolder();
viewHolder.iv_device = (ImageView) convertView.findViewById(R.id.iv_device);
viewHolder.tv_name = (TextView) convertView.findViewById(R.id.tv_name);
viewHolder.tv_mac = (TextView) convertView.findViewById(R.id.tv_mac);
convertView.setTag(viewHolder);
}else{
viewHolder = (ScanResultHolder) convertView.getTag();
}
ScanResult scanResult = getDataList().get(position);
if(scanResult != null){
viewHolder.tv_name.setText(scanResult.SSID);
viewHolder.tv_mac.setText(scanResult.BSSID);
}
return convertView;
}
这是启用hotspot
的代码
public static boolean configApState(Context context, String apName) {
WifiManager wifimanager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
WifiConfiguration wificonfiguration = null;
try {
wificonfiguration = new WifiConfiguration();
wificonfiguration.SSID = apName;
// if WiFi is on, turn it off
if(isApOn(context)) {
wifimanager.setWifiEnabled(false);
// if ap is on and then disable ap
disableAp(context);
}
Method method = wifimanager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
method.invoke(wifimanager, wificonfiguration, !isApOn(context));
return true;
}
catch (Exception e) {
e.printStackTrace();
}
return false;
}