shareit 如何以编程方式发现附近的设备 android
How does shareit discovers nearby devices android programmatically
我想创建一个像 shareit 这样的文件共享应用程序,但我对 shareit 如何发现附近的设备感到很困惑。
当您点击接收按钮分享时,它会在接收方创建一个热点,而没有连接到热点的发送方会显示接收方名称。这怎么可能?
如果 shareit 直接使用 Wi-Fi,那么创建热点有什么意义?
要使用网络服务发现 (NSD),服务器和客户端都应该在同一个网络上,所以我认为 shareit 使用的是其他东西
如果有人能解释一下 shareit 的概念,那将非常有帮助。
终于找到答案了! SHAREit 使用 WiFi SSID 来识别附近的应用程序用户。
SSID 像这样由两部分组成。 BAHD-bXViYQ WHERE 'B' 代表 ANDROID 设备和用户图标的 AHD。第二部分是用Base64编码的用户名。在这个例子中我的名字是 muba。
我希望这个答案有助于节省一些时间。
好吧,我已经找到了如何从一个共享应用程序启用 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
方法只是将该数据列表传递给扫描器以获取网络的 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;
}
我想创建一个像 shareit 这样的文件共享应用程序,但我对 shareit 如何发现附近的设备感到很困惑。
当您点击接收按钮分享时,它会在接收方创建一个热点,而没有连接到热点的发送方会显示接收方名称。这怎么可能?
如果 shareit 直接使用 Wi-Fi,那么创建热点有什么意义?
要使用网络服务发现 (NSD),服务器和客户端都应该在同一个网络上,所以我认为 shareit 使用的是其他东西
如果有人能解释一下 shareit 的概念,那将非常有帮助。
终于找到答案了! SHAREit 使用 WiFi SSID 来识别附近的应用程序用户。 SSID 像这样由两部分组成。 BAHD-bXViYQ WHERE 'B' 代表 ANDROID 设备和用户图标的 AHD。第二部分是用Base64编码的用户名。在这个例子中我的名字是 muba。 我希望这个答案有助于节省一些时间。
好吧,我已经找到了如何从一个共享应用程序启用 hotspot
并将该共享应用程序启用的可用 wifi 列表找到另一个应用程序。就像 shareIt receiver
启用 wifi 热点和 sender discovers
可用列表 receivers
。
首先,您必须使用 WifiManager
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
方法只是将该数据列表传递给扫描器以获取网络的 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;
}