android 开发 自动生成wifi,Android Wi-Fi直连开发指南

如何创建一个使用Wi-Fi P2P的应用

创建使用Wi-Fi P2P功能的应用需要多个步骤,其中包括注册广播接受者,发现设备,连接设备,传输数据等步骤。下面是关于这些步骤的介绍。

初始化设置

在调用wifi-p2p的API前,你须要确保相应设备支持Wi-Fi P2P。如果该设备支持Wi-Fi P2P,那么你可以在你的应用中获取WifiP2pManager实例,并进行广播接受者的创建和注册,以及调用其它Wi-Fi P2P 的API。

1.在manifest文件当中声明相关权限,同时声明你应用的SDK 最小版本号(因为Android4.0才开始支持WiFi直连,所以版本号是14)。

2.检查是WiFi是否开启。一个比较好的检查方式是,当广播接受者收到WIFI_P2P_STATE_CHANGED_ACTION广播时,对其进行判断看WiFi是否开启。然后将WiFi的状态通知给Activity,让其对此作出相应的处理(例如提示用户或者开启WiFi)。

@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

}

}

...

}

3、在你的Activity的onCreate方法当中,获取WifiP2pManager的实例。然后调用initialize()方法来将你的应用注册到 Wi-Fi P2P framework当中,这个方法将会返回一个WifiP2pManager.Channel对象,它把你的应用与底层的 Wi-Fi P2P framework连接起来。

建议你同时创建一个广播接受者,并把WifiP2pManager和WifiP2pManager.Channel以及Activity引用传给它。这可以让你的broadcast receiver在接收到特定时间的广播时,能够很方便的通知Activity或者对Wi-Fi进行操作。

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, this);

...

}

4、创建一个Intent filter,然后把下面这些intent加入其中,这样你的广播接收者就能接收到WiFi变化相应的广播。

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);

...

}

5、在Activity的onResume()方法当中注册广播接受者,在onPause方法当中注销它。

/* register the broadcast receiver with the intent values to be matched */

@Override

protected void onResume() {

super.onResume();

registerReceiver(mReceiver, mIntentFilter);

}

/* unregister the broadcast receiver */

@Override

protected void onPause() {

super.onPause();

unregisterReceiver(mReceiver);

}

发现设备

调用discoverPeers()方法,就可以开始发现周边适合连接的设备。这个方法的调用是异步的,如果你设置了一个WifiP2pManager.ActionListener监听器,那么这个方法的调用结果会通过ActionListener回调返回。onSuccess()方法只告诉你该发现节点的任务执行成功,但不会提供所发现节点的任何信息。

mManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {

@Override

public void onSuccess() {

...

}

@Override

public void onFailure(int reasonCode) {

...

}

});

如果发现节点的任务执行成功,并且检测到了适合节点。系统会发送WIFI_P2P_PEERS_CHANGED_ACTION广播,当你收到这个广播的时候,你就可以调用requestPeers()方法,来获取发现了节点列表。

PeerListListener myPeerListListener;

...

if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {

// request available peers from the wifi p2p manager. This is an

// asynchronous call and the calling activity is notified with a

// callback on PeerListListener.onPeersAvailable()

if (mManager != null) {

mManager.requestPeers(mChannel, myPeerListListener);

}

}

连接节点

当你找到自己想要连接的设备时,你可以通过调用connect()方法来连接这个设备,调用这个方法需要一个WifiP2pConfig对象作为参数。WifiP2pConfig对象包含了进行连接的一些配置信息,包括设备地址,认证方式,谁作为GroupOwner等。这个方法调用的结果会通过WifiP2pManager.ActionListener返回。

//obtain a peer from the WifiP2pDeviceList

WifiP2pDevice device;

WifiP2pConfig config = new WifiP2pConfig();

config.deviceAddress = device.deviceAddress;

mManager.connect(mChannel, config, new ActionListener() {

@Override

public void onSuccess() {

//success logic

}

@Override

public void onFailure(int reason) {

//failure logic

}

});

传输数据

一旦设备间的连接成功建立,你就可以通过socket来传输数据,基本的步骤如下。

1、创建ServerSocket,并调用accept()方法在指定端口等待客户端的连接,注意这个过程将会阻塞线程,请在后台线程完成这个它。

2、创建ClientSocket,然后使用服务器IP和端口去连接充当服务器的设备。

3、 客户端往服务器发送数据。当客户端成功连接上服务器端之后,你就可以以字节流的形式向服务器发送数据了。

4、服务器接收数据。当服务器的accept()接受一个客户端连接之后,服务器端口能够收到客户端发来的数据了。

注意在WiFi P2P连接中,Group Owner和Group Client都能够作为Server Socket,并且当一个Socket连接建立后,双方都可以收发数据。

下面是一个通过WiFi P2P从客户端往服务器端发送图片的例子,以下是服务器端部分代码。

public static class FileServerAsyncTask extends AsyncTask {

private Context context;

private TextView statusText;

public FileServerAsyncTask(Context context, View statusText) {

this.context = context;

this.statusText = (TextView) statusText;

}

@Override

protected String doInBackground(Void... params) {

try {

/**

* Create a server socket and wait for client connections. This

* call blocks until a connection is accepted from a client

*/

ServerSocket serverSocket = new ServerSocket(8888);

Socket client = serverSocket.accept();

/**

* If this code is reached, a client has connected and transferred data

* Save the input stream from the client as a JPEG file

*/

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(WiFiDirectActivity.TAG, e.getMessage());

return null;

}

}

/**

* Start activity that can handle the JPEG image

*/

@Override

protected void onPostExecute(String result) {

if (result != null) {

statusText.setText("File copied - " + result);

Intent intent = new Intent();

intent.setAction(android.content.Intent.ACTION_VIEW);

intent.setDataAndType(Uri.parse("file://" + result), "image/*");

context.startActivity(intent);

}

}

}

以下是客户端部分代码

Context context = this.getApplicationContext();

String host;

int port;

int len;

Socket socket = new Socket();

byte buf[] = new byte[1024];

...

try {

/**

* Create a client socket with the host,

* port, and timeout information.

*/

socket.bind(null);

socket.connect((new InetSocketAddress(host, port)), 500);

/**

* Create a byte stream from a JPEG file and pipe it to the output stream

* of the socket. This data will be retrieved by the server device.

*/

OutputStream outputStream = socket.getOutputStream();

ContentResolver cr = context.getContentResolver();

InputStream inputStream = null;

inputStream = cr.openInputStream(Uri.parse("path/to/picture.jpg"));

while ((len = inputStream.read(buf)) != -1) {

outputStream.write(buf, 0, len);

}

outputStream.close();

inputStream.close();

} catch (FileNotFoundException e) {

//catch logic

} catch (IOException e) {

//catch logic

}

/**

* Clean up any open sockets when done

* transferring or if an exception occurred.

*/

finally {

if (socket != null) {

if (socket.isConnected()) {

try {

socket.close();

} catch (IOException e) {

//catch logic

}

}

}

}

本文档翻译自google官方文档,并作了部分补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值