一号热搜榜,为您提供最新的热搜资讯,热搜榜信息!

WifiDirect (WIFIP2P) 最全最详细,应用于智能硬件(智能家居,车机,无人机)等。

科技热搜 作者:互联网收集 热度:933

WifiDirect (WIFIP2P) 最全最详细,应用于智能硬件(智能家居,车机,无人机)等。

前沿:好久没更博客了,手都快生了。不过但凡长时间的积累之后就会有精品,我希望我这一篇文章能帮助各位正在“坑里”的猿猿们。

产品:你给我调研一个手机连上无网WIFI 后能继续使用手机流量的 需求。WIFI不能自动跳转和改变,(WIFI和移动流量必须同时开启)。

程序员:?????纳尼??2333333~

初听到需求,我于是去啪啪啪的搜了一圈,

搜:wifi和移动流量能同时使用么?wifi连接后,能强行使用移动流量么?等等。。。答案也是千奇百怪。有的需要改开发板,有需要用 wireless-tools 方式驱动WIFI ,通过命令启动 WIFI 模块。也有需要使用wpa_supplicant 方式驱动WIFI .可想而知 ,都没有权限,不符合需求。

WifiDirect (WIFIP2P) 最全最详细,应用于智能硬件(智能家居,车机,无人机)等。

直到遇见了WIFIP2P,一切问题迎刃而解。

背景

使用场景以及连接原理简介 wifip2p是一种点对点,一对多的 角色。通俗点 Android中 称之为WIFI直连,在IOS 中称之为 Airdrop(隔空投送),这种功能很强大,尤其是在智能家居,智能硬件领域。因为蓝牙的传输限制,无法满足更多的需求(比如视频数据的接收)。USB 可以满足这一点不假,但是有距离限制。而且也不是很方便。所以一般我们采用WIFI 连接。这种模式也可以。 查看WIFI网卡/手机网卡状态

如果:这时候你既要连接wifi设备,又要需要请求网络处理数据,怎么办。如今的手机我们都知道只要wifi连接,便中断手机移动数据。这一点我也已经确实的验证过。

运行 —> cmd —> adb shell —> netcfg

通过查看 rmnet0 (手机网卡) 和 wlan0(WIFI连接)的状态 (DOWN 和 UP)。 wifip2p作用

这时候wifip2p 的优点就显示出来的。既可以满足通信要求,又可以不影响手机网络。岂不是很nice。通过wifip2p设备可以直接通过WiFi共享文件,图片等(类似蓝牙传输),实现点对点的连接,通信(要求两设备必须位于同一网段)。在Miracast应用场景中,一台支持P2P的智能手机可直接连接上一台支持P2P的智能电视,智能手机随后将自己的屏幕,或者媒体资源传送给电视机去显示或播放。

显然,借助P2P技术,Wi-Fi设备之间的直接相连将极大拓展Wi-Fi技术的使用场景。 如何判断自己的设备是否支持wifip2p

判断设备是否支持WiFi直连是通过

PackageManager的hasSystemFeature (API)

ps:

getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT);

代码实战

官方文档:http://developer.android.com/intl/zh-tw/guide/topics/connectivity/wifip2p.html

官方Demo: http://download.csdn.net/detail/yichigo/5516627

具体步骤

- 设置应用程序权限

- 创建一个广播接收器

- 初始化对等点的搜索

- 检查设备WIFI 是否开启,

- 只有上面的一步打开,才能开始搜索对等点

- 搜索到对等点列表,拿到列表信息

- 建立一个对等点连接

1.首先把需要的权限都配置好

< uses-permission android:name = 'android.permission.ACCESS_WIFI_STATE' /> < uses-permission android:name = 'android.permission.CHANGE_WIFI_STATE' /> < uses-permission android:name = 'android.permission.CHANGE_NETWORK_STATE' /> < uses-permission android:name = 'android.permission.INTERNET' /> < uses-permission android:name = 'android.permission.ACCESS_NETWORK_STATE' /> < uses-permission android:name = 'android.permission.WRITE_EXTERNAL_STORAGE' /> < uses-permission android:name = 'android.permission.READ_EXTERNAL_STORAGE' />

2.需要监听WIFIP2P的广播

import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.NetworkInfo; import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pDeviceList; import android.net.wifi.p2p.WifiP2pInfo; import android.net.wifi.p2p.WifiP2pManager; import android.text.TextUtils; import android.util.Log; import java.util.ArrayList; import java.util.List; public class DirectBroadcastReceiver extends BroadcastReceiver { private static final String TAG = 'DirectBroadcastReceiver' ; private WifiP2pManager mWifiP2pManager; private WifiP2pManager.Channel mChannel; /**是一个自定义监听 回调接口**/ private WifiDirectActionListener mWifiDirectActionListener; public DirectBroadcastReceiver (WifiP2pManager wifiP2pManager, WifiP2pManager.Channel channel, DirectActionListener directActionListener) { mWifiP2pManager = wifiP2pManager; mChannel = channel; mDirectActionListener = directActionListener; } public static IntentFilter getIntentFilter () { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); return intentFilter; } @Override public void onReceive (Context context, Intent intent) { Log.e(TAG, '接收到广播: ' + intent.getAction()); if (!TextUtils.isEmpty(intent.getAction())) { switch (intent.getAction()) { /**用于指示 Wifi P2P 是否可用**/ case WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION: int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, - 1 ); if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) { mWifiDirectActionListener.wifiP2pEnabled( true ); } else { mWifiDirectActionListener.wifiP2pEnabled( false ); List wifiP2pDeviceList = new ArrayList<>(); mWifiDirectActionListener.onPeersAvailable(wifiP2pDeviceList); } break ; /**表明可用的对等点的列表发生了改变 **/ case WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION: mWifiP2pManager.requestPeers(mChannel, new WifiP2pManager.PeerListListener() { @Override public void onPeersAvailable (WifiP2pDeviceList peers) { mWifiDirectActionListener.onPeersAvailable(peers.getDeviceList()); } }); break ; /**表示Wi-Fi对等网络的连接状态发生了改变 **/ case WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION: NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); if (networkInfo.isConnected()) { mWifiP2pManager.requestConnectionInfo(mChannel, new WifiP2pManager.ConnectionInfoListener() { @Override public void onConnectionInfoAvailable (WifiP2pInfo info) { if (info != null ) { Log.i(TAG, '确实获取到WiFip2pinfo' ); } else { Log.i(TAG, 'WiFip2pinfo 为null' ); } mWifiDirectActionListener.onConnectionInfoAvailable(info); } }); Log.i(TAG, '已连接P2P' ); } else { mWifiDirectActionListener.onDisconnection(); Log.i(TAG, '与P2P设备已断开连接' ); } break ; /**表示该设备的配置信息发生了改变**/ case WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION: mWifiDirectActionListener.onSelfDeviceAvailable((WifiP2pDevice) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)); break ; default : break ; } } } }

自定义回调监听

public interface WifiDirectActionListener extends WifiP2pManager . ChannelListener { void wifiP2pEnabled( boolean enabled); void onConnectionInfoAvailable(WifiP2pInfo wifiP2pInfo); void onDisconnection(); void onSelfDeviceAvailable(WifiP2pDevice wifiP2pDevice); void onPeersAvailable(Collection wifiP2pDeviceList); }

3.初始化WIFIP2P的config,并且开始搜索

【!!!在我开发过程,我发现需要真正的搜索到列表,必须多台设备都处于搜索状态,否自不处于搜索的那个设备是不会出现在DeviceList中,可以尝试熄屏,后台状态。】

private WifiP2pManager mWifiP2pManager; private WifiP2pManager.Channel mChannel; private WifiP2pDevice mWifiP2pDevice; private BroadcastReceiver broadcastReceiver; private boolean mWifiP2pEnabled = false ; private List mWifiP2pDeviceList; private void initConfig () { mWifiP2pManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); mChannel = mWifiP2pManager.initialize( this , getMainLooper(), this ); broadcastReceiver = new DirectBroadcastReceiver(mWifiP2pManager, mChannel, this ); registerReceiver(broadcastReceiver, DirectBroadcastReceiver.getIntentFilter()); mWifiP2pDeviceList = new ArrayList<>(); }

接着开始搜索列表

mWifiP2pManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess () { showToast( 'Success' ); } @Override public void onFailure ( int reasonCode) { showToast( 'Failure' ); } });

如果写了Adapter 就可以直接看到列表有多少个 对等点。同样也可以直接在广播中打log

case WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION: ????? break ;

同时,我们可以获取到当前设备的一些基本信息。在广播

case WifiP2pManager .WIFI _P2P_THIS_DEVICE_CHANGED_ACTION: mDirectActionListener .onSelfDeviceAvailable ((WifiP2pDevice) intent .getParcelableExtra (WifiP2pManager .EXTRA _WIFI_P2P_DEVICE)) break

@Override public void onSelfDeviceAvailable(WifiP2pDevice wifiP2pDevice) { Log . i( TAG , 'DeviceName: ' + wifiP2pDevice . deviceName); Log . i( TAG , 'DeviceAddress: ' + wifiP2pDevice . deviceAddress); Log . i( TAG , 'Status: ' + wifiP2pDevice . status); }

先贴出一张API参数信息。

4.在接着就是连接P2P

注意:这里很值得说一说。我们调用manager中的connect方法,

①如果连接之前没有创建一个组,系统会自动创建一个组,并且随机分配谁是GroupOwner即谁是组长,

②创建一个组,谁创建谁就是组长。

③这也关系到谁是客户端谁是服务器,

为什么要重点提示谁是组长?因为这里有坑,就是组长只有接受数据的能力,非组长拥有发送数据的能力。并不是谁都可以随便发送和接收,因为Socket 建立需要IP,而WIFIP2P 连接后并不能获取到客户机的IP。只能获取到组长的IP 。也就是 wifiP2pInfo.groupOwnerAddress.getHostAddress()

PS: 一开始我也不知道问题出在那里,后来就查到大家都有这种问题。

https://bbs.csdn.net/topics/390780179/

最近在研究wifi direct

,主要是通过IWIFIP2PManager类来操作,但是我发现,当成功建立连接后,好像从ConnectInfo中(WIFIP2PInfo)中只能获取GroupOwner的IpAddress,并没有API可以提供其他Device的IpAdress。这个会导致上层应用无法获得对端Ip地址,而无法传递数据等。由于在不同的场景下,任何设备都有可能是GroupOwner,而我们除了GroupOwner的Ip

Address外,还希望能获取对端以及Group中所有成员的Ip Address,包括自己的Ip Address.

private void connect () { WifiP2pConfig config = new WifiP2pConfig(); if (config.deviceAddress != null && mWifiP2pDevice != null ) { config.deviceAddress = mWifiP2pDevice.deviceAddress; config.wps.setup = WpsInfo.PBC; mWifiP2pManager.connect(mChannel, config, new WifiP2pManager.ActionListener() { @Override public void onSuccess () { Log.e(TAG, 'connect onSuccess' ); } @Override public void onFailure ( int reason) { Log.e(TAG, 'connect fail' ); } }); } }

主动创建组长

private void createroup () { mWifiP2pManager.createGroup(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess () { Log.e(TAG, 'createGroup onSuccess' ); showToast( 'onSuccess' ); } @Override public void onFailure ( int reason) { Log.e(TAG, 'createGroup onFailure: ' + reason); showToast( 'onFailure' ); } }); }

同样,断开连接就是 移除组就可以了。

private void disconnect () { mWifiP2pManager.removeGroup(mChannel, new WifiP2pManager.ActionListener() { @Override public void onFailure ( int reasonCode) { Log.i(TAG, 'disconnect onFailure:' + reasonCode); } @Override public void onSuccess () { Log.i(TAG, 'disconnect onSuccess' ); } }); }

4.数据连接阶段,非组长(群主)代码

开启异步操作。

new WifiClientTask( this , fileTransfer).execute(wifiP2pInfo.groupOwnerAddress.getHostAddress()); /**这里的 fileTransfer 就是需要传输的 Object 自定义个Bean 就好 ,重写 Serializable 而wifiP2pInfo.groupOwnerAddress.getHostAddress() 就是组IP**/

public class WifiClientTask extends AsyncTask { private ProgressDialog progressDialog; private FileTransfer fileTransfer; private static final int PORT = 4786 ; private static final String TAG = 'WifiClientTask' ; public WifiClientTask (Context context, FileTransfer fileTransfer) { this .fileTransfer = fileTransfer; progressDialog = new ProgressDialog(context); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setCancelable( false ); progressDialog.setCanceledOnTouchOutside( false ); progressDialog.setTitle( '正在发送文件' ); progressDialog.setMax( 100 ); } @Override protected void onPreExecute () { progressDialog.show(); } @Override protected Boolean doInBackground (String... strings) { fileTransfer.setMd5(Md5Util.getMd5( new File(fileTransfer.getFilePath()))); Log.i(TAG, '文件的MD5码值是:' + fileTransfer.getMd5()); Socket socket = null ; OutputStream outputStream = null ; ObjectOutputStream objectOutputStream = null ; InputStream inputStream = null ; try { socket = new Socket(); socket.bind( null ); Log.i(TAG, 'IP:' + strings[ 0 ] + 'PORT:' + PORT); socket.connect(( new InetSocketAddress(strings[ 0 ], PORT)), 10000 ); outputStream = socket.getOutputStream(); objectOutputStream = new ObjectOutputStream(outputStream); objectOutputStream.writeObject(fileTransfer); inputStream = new FileInputStream( new File(fileTransfer.getFilePath())); long fileSize = fileTransfer.getFileLength(); long total = 0 ; byte buf[] = new byte [ 512 ]; int len; while ((len = inputStream.read(buf)) != - 1 ) { outputStream.write(buf, 0 , len); total += len; int progress = ( int ) ((total * 100 ) / fileSize); publishProgress(progress); Log.i(TAG, '文件发送进度:' + progress); } outputStream.close(); objectOutputStream.close(); inputStream.close(); socket.close(); outputStream = null ; objectOutputStream = null ; inputStream = null ; socket = null ; Log.i(TAG, '文件发送成功' ); return true ; } catch (Exception e) { Log.i(TAG, '文件发送异常 Exception: ' + e.getMessage()); } finally { if (outputStream != null ) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (objectOutputStream != null ) { try { objectOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (inputStream != null ) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (socket != null ) { try { socket.close(); } catch (Exception e) { e.printStackTrace(); } } } return false ; } @Override protected void onProgressUpdate (Integer... values) { progressDialog.setProgress(values[ 0 ]); } @Override protected void onPostExecute (Boolean aBoolean) { progressDialog.cancel(); Log.i(TAG, 'onPostExecute: ' + aBoolean); } }

而Socket.accept 等待方 开启IntentService

public class WifiServerService extends IntentService { private static final String TAG = 'WifiServerService' ; public interface OnProgressChangListener { void onProgressChanged(FileTransfer fileTransfer, int progress); void onTransferFinished(File file); } private ServerSocket serverSocket; private InputStream inputStream; private ObjectInputStream objectInputStream; private FileOutputStream fileOutputStream; private OnProgressChangListener progressChangListener; private static final int PORT = 4786 ; public class MyBinder extends Binder { public WifiServerService getService () { return WifiServerService. this ; } } public WifiServerService () { super ( 'WifiServerService' ); Log.i(TAG, 'WifiServerService' ); } @Override public void onCreate () { super .onCreate(); Log.i(TAG, 'onCreate' ); } @Nullable @Override public IBinder onBind (Intent intent) { Log.i(TAG, 'onBind' ); return new MyBinder(); } @Override protected void onHandleIntent (Intent intent) { Log.i(TAG, 'onHandleIntent' ); clean(); File file = null ; try { serverSocket = new ServerSocket(); serverSocket.setReuseAddress( true ); serverSocket.bind( new InetSocketAddress(PORT)); Socket client = serverSocket.accept(); Log.i(TAG, '客户端IP地址 : ' + client.getInetAddress().getHostAddress()); inputStream = client.getInputStream(); objectInputStream = new ObjectInputStream(inputStream); /**如果你写的是2个程序,尽管FileTransfer一样,但是也要注意包名,其实只要Socket 连接通,客户端IP 拿到,就达到了目标。**/ FileTransfer fileTransfer = (FileTransfer) objectInputStream.readObject(); Log.i(TAG, '待接收的文件: ' + fileTransfer); String name = new File(fileTransfer.getFilePath()).getName(); file = new File(Environment.getExternalStorageDirectory() + '/' + name); fileOutputStream = new FileOutputStream(file); byte buf[] = new byte [ 512 ]; int len; long total = 0 ; int progress; while ((len = inputStream.read(buf)) != - 1 ) { fileOutputStream.write(buf, 0 , len); total += len; progress = ( int ) ((total * 100 ) / fileTransfer.getFileLength()); Log.i(TAG, '文件接收进度: ' + progress); if (progressChangListener != null ) { progressChangListener.onProgressChanged(fileTransfer, progress); } } serverSocket.close(); inputStream.close(); objectInputStream.close(); fileOutputStream.close(); serverSocket = null ; inputStream = null ; objectInputStream = null ; fileOutputStream = null ; Log.i(TAG, '文件接收成功,文件的MD5码是:' + Md5Util.getMd5(file)); } catch (Exception e) { Log.i(TAG, '文件接收 Exception: ' + e.getMessage()); } finally { clean(); if (progressChangListener != null ) { progressChangListener.onTransferFinished(file); } startService( new Intent( this , WifiServerService.class)); } } @Override public void onDestroy () { super .onDestroy(); clean(); } public void setProgressChangListener (OnProgressChangListener progressChangListener) { this .progressChangListener = progressChangListener; } private void clean () { if (serverSocket != null ) { try { serverSocket.close(); serverSocket = null ; } catch (IOException e) { e.printStackTrace(); } } if (inputStream != null ) { try { inputStream.close(); inputStream = null ; } catch (IOException e) { e.printStackTrace(); } } if (objectInputStream != null ) { try { objectInputStream.close(); objectInputStream = null ; } catch (IOException e) { e.printStackTrace(); } } if (fileOutputStream != null ) { try { fileOutputStream.close(); fileOutputStream = null ; } catch (IOException e) { e.printStackTrace(); } } } }

其实Demo 我也是从githup上拿到的。但是同样我也将我自己遇到的坑总结了一翻,彻底明白了WIFIP2P 。

https://github.com/leavesC/WifiP2P

总结【精华】

WIFIP2P连接成功后,要注意,只有非群主才能向群主发送Socket建立,并能成功发送数据。

~ ~~~~

原因:当成功建立连接后,从WIFIP2PInfo中只能获取GroupOwner的IpAddress,并没有API可以提供其他Device的IpAdress。这个会导致上层应用无法获得对端Ip地址,而无法传递数据等。由于在不同的场景下,任何设备都有可能是GroupOwner,而我们除了GroupOwner的Ip Address外,还希望能获取对端以及Group中所有成员的Ip Address,包括自己的Ip Address. WIFIP2P 建连后(connect方法),如果连接之前没有创建一个组,系统会自动创建一个组,并且随机分配谁是GroupOwner即谁是组长,这也关系到谁是客户端谁是服务器.

~ ~~~~

问题:这有个坑,非常大的几率 他会一直锁定一个Device 为群主,不管是A 连接B ,还是B 连接 A, 还是A 连接C。所以一定要确定 wifiinfo 中

wifiP2pInfo.groupFormed——–一定要为true ,这样wifiinfo才包含有用信息

wifiP2pInfo.isGroupOwner——–一定要为false,是非群主,见1.才有可能发送信息。

~ ~~~~

如何解决:API 也有方法提供

调用 wifiP2pManager.createGroup(channel, new WifiP2pManager.ActionListener() {},在未连接p2p 之前,在你想要当做服务器的(AP)的机子上提前 createGroup,并在开始连接。就可以结局随机组长的问题。 WifiP2pDevice 的意思是【本机设备信息】,所以千万不要误以为是获取到的是另外一台设备的设备信息。

其中常用有:

wifiP2pDevice.deviceName 本设备名字

wifiP2pDevice.deviceAddress 本设备的MAC地址

wifiP2pDevice.status 设备连接状态

~ ~~~~

重点!!! 千万不要以为 wifiP2pDevice.status

(0是连接 ,1是邀请中,3是未连接,但是可用,4是不可用)

为0的时候就是连接了,问题在于:p2p连接了,status 一定为0,但是status 为0 ,p2p不一定真正的连接了。这种情况在连接【智能设备】的时候容易出现,我就在此被坑了。真正的wifip2p 连接成功,必须要 在

WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION

广播中获得 为true

intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO).isConnected()

并且通过

mWifiP2pManager.requestConnectionInfo(?,?);的回调监听,拿到wifiinfo的实体 ,且不为空。 才算的上你真正的加入p2p组。 至此,wifip2p 连接问题 的问题点基本已经解决。真正连接后p2p 后就要建立Socket连接。一般是没有问题的,有问题也只有2点 1.)文件路径没有获取到,我们通过intent 获取到的 一般是 Uri

content://com.android.providers.media.documents/document/image%3A63

而我们想要的是文件绝对路径

/data/hw_init/version/region_comm/china/media/Pre-loaded/Pictures/01-04.jpg

这样才能 通过 File file = new File(path); 文件。

所以注意这一点路径转换过程 是否为空

~~

2.)socket 服务器等待方 serverSocket.accept();

其实也只是 要保证是否在等待。

楼主使用的是Githup的Demo ,其中serverSocket.accept(); 是在intentservice 的

onHandleIntent 中开启的,这个intentservice 的 开启有2种方式,startService 和

bindService 一般我们喜欢使用bindService ,毕竟数据接收后需要处理,通知UI 线程。

但是bingService 的生命周期 是不走 onHandleIntent. 而 startService 是走的。具体看我另外一篇博客对Service 和IntentService 的 解释。(下面是链接)

https://blog.csdn.net/qq_31332467/article/details/82430638 在开发过程中发现,WIFIP2P连接,必须双向设备都处于discoverPeers状态中,如果一方不在该状态中,则另一方根本拿不到设备列表,拿不到就谈不了最基本的连接

后记

因为我连接的硬件是车机,车机开发板中有很多问题,可能对Android开发板做了修改,我这边就遇到2个问题:

1.一个车机是有WIFI ,但是却没有直连模块,问了供货商,他们说没改过。可是开了广播后,无论如何都拿不到广播,根本连onReceive 都没走。那就什么都不用谈了,列表都拿不到,还说什么。

2.换了一台车机(另一个供货商的),这个就很顺利的拿到了列表。果然供应商都是。。。。但是这个更坑,让我白高兴了一场。

顺利拿到了列表,也顺利连接上了,只是mWifiP2pManager.connect()中回调成功。我以为连接OK,就开始Socket建连,可无论如何都是提示 Connection refusal!

我怎么就不明白,难道开发商的车机觉得我的客户端IP 非法,给我拒绝了?

一直就认为是套接字的问题。后来才发现,其实根本就没连接上,关键在广播中的

case WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION: NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); if (networkInfo.isConnected()) { mWifiP2pManager.requestConnectionInfo(mChannel, new WifiP2pManager.ConnectionInfoListener() { @Override public void onConnectionInfoAvailable (WifiP2pInfo info) { if (info != null ) { /**!!!!只有真正的走到这里才是真正连接!!!!**/ } else { Log.i(TAG, 'WiFip2pinfo 为null' ); } mDirectActionListener.onConnectionInfoAvailable(info); } }); Log.i(TAG, '已连接P2P' ); } else { mDirectActionListener.onDisconnection(); Log.i(TAG, '与P2P设备已断开连接' ); } break ;

然后在赋值WifiP2pInfo 的时候,更要注意:

@Override public void onConnectionInfoAvailable (WifiP2pInfo wifiP2pInfo) { Log.i(TAG, 'onConnectionInfoAvailable groupFormed: ' + wifiP2pInfo.groupFormed); Log.i(TAG, 'onConnectionInfoAvailable isGroupOwner: ' + wifiP2pInfo.isGroupOwner); Log.i(TAG, 'onConnectionInfoAvailable getHostAddress: ' + wifiP2pInfo.groupOwnerAddress.getHostAddress()); /**必须if条件成立才可以开启 AsyncTask**/ if (wifiP2pInfo.groupFormed && !wifiP2pInfo.isGroupOwner) { Log.e(TAG, 'F-Z-C-G' ); this .wifiP2pInfo = wifiP2pInfo; } }

本章完结

标签: 智能家居     WifiDirect     WIFIP2P