WiFi点对点传输不用连接网络和热点,可进行近距离通信,比蓝牙传输要远,速度更快。
1.初始化
1.1配置权限
Android点对点传输只能在Android 4.0 (API level 14)以后的版本中使用;
也可以在代码中进行判断 是否支持WiFi点对点传输 定义一个接收WIFI_P2P_STATE_CHANGED_ACTION 的IntentFiltert的BroadcastReceiver
@Override
public void onReceive(Context context, Intent intent) {
...
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
// Wifi P2P is enabled
} else {
// Wi-Fi P2P is not enabled
}
}
...
}
1.2获取 WifiP2pManager.Channel
WifiP2pManager mManager;
Channel mChannel;
BroadcastReceiver mReceiver;
...
@Override
protected void onCreate(Bundle savedInstanceState){
...
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel);
...
}
1.3创建广播接收器接收Wi-Fi P2P Intents
IntentFilter mIntentFilter;
...
@Override
protected void onCreate(Bundle savedInstanceState){
...
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
...
}
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager mManager;
private Channel mChannel;
public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel) {
super();
this.mManager = manager;
this.mChannel = channel;
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
//判断是否支持 wifi点对点传输
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
// 查找到设备列表
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
//获取到连接状态改变的详细信息
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
//自身设备信息改变
}
}
}
1.4注册BroadcastReceiver
@Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}
2.查找设备
mManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
...
}
@Override
public void onFailure(int reasonCode) {
...
}
});
3.发现设备
系统会发送一条WIFI_P2P_PEERS_CHANGED_ACTION广播,然后调用 requestPeers在myPeerListListener获取设备列表
PeerListListener myPeerListListener;
...
if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
if (mManager != null) {
mManager.requestPeers(mChannel, myPeerListListener);
}
}
4.连接设备
WifiP2pDevice device;
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.wps.setup = WpsInfo.PBC;
mManager.connect(mChannel, config, new ActionListener() {
@Override
public void onSuccess() {
//success logic
}
@Override
public void onFailure(int reason) {
//failure logic
}
});
5.获取连接状态信息
连接后会系统会发送WIFI_P2P_CONNECTION_CHANGED_ACTION广播可在此处获取NetworkInfo,然后调用requestConnectionInfo获取连接信息
else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
if (manager == null) {
return;
}
NetworkInfo networkInfo = intent
.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()) {
manager.requestConnectionInfo(channel, myConnectionInfoListener);
} else {
}
}
//在myConnectionInfoListener回调onConnectionInfoAvailable方法中获取到WifiP2pInfo
myConnectionInfoListener = new WifiP2pManager.ConnectionInfoListener() {
@Override
public void onConnectionInfoAvailable(WifiP2pInfo info) {
if (info != null) {
mInfo = info;
if (info.groupFormed && info.isGroupOwner) {
new FileServerAsyncTask(MainActivity.this, MainActivity.this.findViewById(R.id.status_text))
.execute();
} else if (info.groupFormed) {
}
}
}
};
6.传输数据
6.1服务器端(info.isGroupOwner作为服务器端)新建AsyncTask绑定端口等待连接,接收到图片数据后进行展示:
public static class FileServerAsyncTask extends AsyncTask {
private Context context;
public FileServerAsyncTask(Context context, View statusText) {
this.context = context;
}
@Override
protected String doInBackground(Void... params) {
try {
ServerSocket serverSocket = new ServerSocket(8988);
Socket client = serverSocket.accept();
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
+ ".jpg");
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
InputStream inputstream = client.getInputStream();
copyFile(inputstream, new FileOutputStream(f));
serverSocket.close();
return f.getAbsolutePath();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
return null;
}
}
@Override
protected void onPostExecute(String result) {
if (result != null) {
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + result), "image/*");
context.startActivity(intent);
}
}
}
6.2客户端:发送图片给服务器端
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE);
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
Uri uri = data.getData();
Intent serviceIntent = new Intent(this, FileTransferService.class);
serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS,
mInfo.groupOwnerAddress.getHostAddress());
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8988);
startService(serviceIntent);
}
}
public static class FileTransferService extends IntentService {
private static final int SOCKET_TIMEOUT = 3600;
public static String ACTION_SEND_FILE = "android.intent.action.SEND_FILE";
public static String EXTRAS_FILE_PATH = "extras_file_path";
public static String EXTRAS_GROUP_OWNER_ADDRESS = "extras_group_owner_address";
public static String EXTRAS_GROUP_OWNER_PORT = "extras_group_owner_port";
public FileTransferService(String name) {
super(name);
}
public FileTransferService() {
super("FileTransferService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
Context context = getApplicationContext();
if (intent.getAction().equals(ACTION_SEND_FILE)) {
String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);
String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS);
Socket socket = new Socket();
int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
try {
socket.bind(null);
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
OutputStream stream = socket.getOutputStream();
ContentResolver cr = context.getContentResolver();
InputStream is = null;
try {
is = cr.openInputStream(Uri.parse(fileUri));
} catch (FileNotFoundException e) {
Log.d(TAG, e.toString());
}
copyFile(is, stream);
} catch (IOException e) {
} finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
}
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[1024];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
} catch (IOException e) {
return false;
}
return true;
}
7.断开连接
if (mManager != null) {
if (mDevice == null
|| mDevice.status == WifiP2pDevice.CONNECTED) {
mManager.removeGroup(mChannel, new WifiP2pManager.ActionListener() {
@Override
public void onFailure(int reasonCode) {
Log.d(TAG, "Disconnect failed. Reason :" + reasonCode);
}
@Override
public void onSuccess() {
btnSearch.setText("search");
}
});
} else if (mDevice.status == WifiP2pDevice.AVAILABLE
|| mDevice.status == WifiP2pDevice.INVITED) {
mManager.cancelConnect(mChannel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
btnSearch.setText("search");
Toast.makeText(MainActivity.this, "Aborting connection",
Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(int reasonCode) {
Toast.makeText(MainActivity.this,
"Connect abort request failed. Reason Code: " + reasonCode,
Toast.LENGTH_SHORT).show();
}
});
}
}
看到评论需要源码
源码下载地址