一、添加权限
<!--允许程序访问wifi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允许程序改变wifi状态-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- 允许程序访问网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--允许程序改变网络状态-->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--允许程序访问网络-->
<uses-permission android:name="android.permission.INTERNET"/>
二、打开系统wifi
private void initWifi () {
//获取wifi管理类
mWifiManager = (WifiManager) getSystemService (Context.WIFI_SERVICE);
//打开wifi
if(mWifiManager!=null){
mWifiManager.setWifiEnabled (true);
}
}
三、初始化WifiP2pManager
private void initWifiP2P () {
//获取wifiP2p管理类
mWifiP2pManager = (WifiP2pManager) getSystemService (Context.WIFI_P2P_SERVICE);
//初始化通道
mChannel = mWifiP2pManager.initialize (this, getMainLooper (), null);
}
四、注册与WifiP2pManager有关的广播
private void initIntentFilter () {
mIntentFilter = new IntentFilter ();
//wifiP2p是否可用状态改变的广播动作
mIntentFilter.addAction (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
//wifiP2p搜索状态改变的广播动作
mIntentFilter.addAction (WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
//wifiP2p设备列表发生改变的广播动作
mIntentFilter.addAction (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
//wifiP2p设备连接状态发生改变的广播动作
mIntentFilter.addAction (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
//wifiP2p设备本身信息发生改变的广播动作
mIntentFilter.addAction (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
}
private void initReceiver () {
mReceiver = new WifiP2pBroadcastReceiver (this,mWifiP2pManager,mChannel,mPeerListListener,mConnectionInfoListener);
}
//注册wifiP2p有关的广播
registerReceiver (mReceiver,mIntentFilter);
下面是WifiP2pBroadcastReceiver类
package com.ysy.mywifip2p.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.util.Log;
import android.widget.Toast;
/**
* Created by shuangyue on 2016/9/21 10:51.
*/
public class WifiP2pBroadcastReceiver extends BroadcastReceiver {
public static final String TAG = "BroadcastReceiver";
private Context mContext;
private WifiP2pManager mWifiP2pManager;
private WifiP2pManager.Channel mChannel;
private WifiP2pManager.PeerListListener mPeerListListener;
private WifiP2pManager.ConnectionInfoListener mConnectionInfoListener;
public WifiP2pBroadcastReceiver(Context mContext,WifiP2pManager mWifiP2pManager, WifiP2pManager.Channel mChannel,
WifiP2pManager.PeerListListener mPeerListListener,
WifiP2pManager.ConnectionInfoListener mConnectionInfoListener){
this.mContext = mContext;
this.mWifiP2pManager = mWifiP2pManager;
this.mChannel = mChannel;
this.mPeerListListener = mPeerListListener;
this.mConnectionInfoListener = mConnectionInfoListener;
}
@Override
public void onReceive (Context context, Intent intent) {
String action = intent.getAction ();
if(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals (action)){
int wifiState = intent.getIntExtra (WifiP2pManager.EXTRA_WIFI_STATE, -1);
if(WifiP2pManager.WIFI_P2P_STATE_DISABLED == wifiState){
Log.d (TAG, "onReceive: WIFI_P2P_STATE_DISABLED");
}else if(WifiP2pManager.WIFI_P2P_STATE_ENABLED == wifiState){
Log.d (TAG, "onReceive: WIFI_P2P_STATE_ENABLED");
}
}else if(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION.equals (action)){
int dicoverState = intent.getIntExtra (WifiP2pManager.EXTRA_DISCOVERY_STATE, -1);
if(WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED == dicoverState){
toast ("开始搜索");
Log.d (TAG, "onReceive: WIFI_P2P_DISCOVERY_STARTED");
}else if(WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED == dicoverState){
toast ("停止搜索");
Log.d (TAG, "onReceive: WIFI_P2P_DISCOVERY_STOPPED");
}
}else if(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals (action)){
if(mWifiP2pManager!=null){
mWifiP2pManager.requestPeers (mChannel,mPeerListListener);
}
}else if(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals (action)){
NetworkInfo mNetworkInfo = intent.getParcelableExtra (WifiP2pManager.EXTRA_NETWORK_INFO);
if(mNetworkInfo.isConnected ()){
toast ("已经连接");
if(mWifiP2pManager!=null){
mWifiP2pManager.requestConnectionInfo (mChannel,mConnectionInfoListener);
}
}else{
toast ("连接断开");
}
}else if(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals (action)){
Log.d (TAG, "onReceive: WIFI_P2P_THIS_DEVICE_CHANGED_ACTION");
}
}
private void toast(String text){
Toast.makeText (mContext,text,Toast.LENGTH_SHORT).show ();
}
}
五、搜索周边设备,将搜索到的设备添加到ListView中显示出来
//搜索设备
private void discoverDevice () {
//在搜索设备前,清理ListView中的数据
datas.clear ();
adapter.notifyDataSetChanged ();
/**
* 开始搜索
* ActionListener,该监听只监听discoverPeers方法是否调用成功
*/
mWifiP2pManager.discoverPeers (mChannel, new WifiP2pManager.ActionListener () {
@Override
public void onSuccess () {
}
@Override
public void onFailure (int i) {
}
});
}
//搜索到设备的监听
WifiP2pManager.PeerListListener mPeerListListener = new WifiP2pManager.PeerListListener () {
@Override
public void onPeersAvailable (WifiP2pDeviceList wifiP2pDeviceList) {
//获取设备列表
Collection<WifiP2pDevice> deviceList = wifiP2pDeviceList.getDeviceList ();
//遍历设备列表,将设备添加到ListView中
Iterator<WifiP2pDevice> iterator = deviceList.iterator ();
while(iterator.hasNext ()){
WifiP2pDevice wifiP2pDevice = iterator.next ();
if(!datas.contains (wifiP2pDevice)){
datas.add (wifiP2pDevice);
adapter.notifyDataSetChanged ();
}
}
}
};
六、点击设备进行连接
//建立连接
private void connect (WifiP2pDevice wifiP2pDevice) {
toast (wifiP2pDevice.deviceName);
//创建wifip2p配置对象
WifiP2pConfig config = new WifiP2pConfig ();
//将设备地址设置到配置对象中
config.deviceAddress = wifiP2pDevice.deviceAddress;
//连接
mWifiP2pManager.connect (mChannel, config, new WifiP2pManager.ActionListener () {
@Override
public void onSuccess () {
}
@Override
public void onFailure (int i) {
}
});
}
七、连接监听,如果是主动连接,则显示发送数据按钮,如果是被动连接,则是启动异步任务,等待连接,接收数据。
//连接设备的监听
WifiP2pManager.ConnectionInfoListener mConnectionInfoListener = new WifiP2pManager.ConnectionInfoListener () {
@Override
public void onConnectionInfoAvailable (WifiP2pInfo wifiP2pInfo) {
mWifiP2pInfo = wifiP2pInfo;
if(wifiP2pInfo.isGroupOwner && wifiP2pInfo.groupFormed){//接收端
Log.d ("yxy", "onConnectionInfoAvailable: 接收端");
//使用异步任务,开启ServerSocket,等待客户端去连接
DataAsyncTask dataAsyncTask = new DataAsyncTask ();
dataAsyncTask.executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR);
}else{//发送端
//显示发送按钮,允许用户点击发送按钮,发送数据。
btn_send.setVisibility (View.VISIBLE);
}
}
};
下面是DataAsyncTask类。
package com.ysy.mywifip2p.task;
import android.os.AsyncTask;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by shuangyue on 2016/9/22 9:46.
*/
public class DataAsyncTask extends AsyncTask<Void,Void,String> {
@Override
protected void onPreExecute () {
super.onPreExecute ();
}
@Override
protected String doInBackground (Void... voids) {
String str = null;
try {
ServerSocket serverSocket = new ServerSocket (8999);
//等待客户端来连接
Socket client = serverSocket.accept ();
InputStream is = client.getInputStream ();
ByteArrayOutputStream baos = new ByteArrayOutputStream ();
int i = 0;
while((i = is.read ())!=-1){
baos.write (i);
}
str = baos.toString ();
serverSocket.close ();
} catch (IOException e) {
e.printStackTrace ();
}
return str;
}
@Override
protected void onProgressUpdate (Void... values) {
super.onProgressUpdate (values);
}
@Override
protected void onPostExecute (String s) {
super.onPostExecute (s);
Log.d ("yxy", "onPostExecute: "+s);
}
}
八、点击发送按钮,建立socket连接,发送数据。
private void sendData () {
//创建意图对象
Intent service = new Intent (MainActivity.this, DataService.class);
//设置动作
service.setAction (DataService.ACTION_SEND_DATA);
//设置参数,socket主机号,和端口号
service.putExtra (DataService.SOCKET_HOST,mWifiP2pInfo.groupOwnerAddress.getHostAddress ());
service.putExtra (DataService.SOCKET_PORT,8999);
//启动服务发送数据
MainActivity.this.startService (service);
}
下面是DataService类
package com.ysy.mywifip2p.service;
import android.app.IntentService;
import android.content.Intent;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
/**
* Created by shuangyue on 2016/9/22 9:57.
*/
public class DataService extends IntentService {
public static final String ACTION_SEND_DATA = "send data";
public static final String SOCKET_HOST = "socket host";
public static final String SOCKET_PORT = "socket port";
public DataService (String name) {
super (name);
}
public DataService(){
super("DataService");
}
@Override
protected void onHandleIntent (Intent intent) {
if(ACTION_SEND_DATA.equals (intent.getAction ())){
String host = intent.getExtras ().getString (SOCKET_HOST);
int port = intent.getExtras ().getInt (SOCKET_PORT);
Socket socket = new Socket ();
OutputStream os = null;
try {
socket.bind (null);
socket.connect (new InetSocketAddress (host,port),5000);
os = socket.getOutputStream ();
os.write ("ysy".getBytes ());
} catch (IOException e) {
e.printStackTrace ();
}finally {
if(socket.isConnected ()){
try {
socket.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
}
}
}
九、总结
以上便是android wifi direct 的工作流程,从搜索到连接,再到发送数据与接收数据。
参考资料:1、http://blog.csdn.net/mikogodzd/article/details/50965178
2、developer
十、Demo下载地址