设为首页 收藏本站
查看: 1198|回复: 0

[经验分享] Wifi-Direct

[复制链接]

尚未签到

发表于 2015-9-30 13:32:59 | 显示全部楼层 |阅读模式
  参考链接:http://developer.android.com/guide/topics/connectivity/wifip2p.html
  国内镜像开发文档:http://wear.techbrood.com/guide/topics/connectivity/wifip2p.html
  

API:
  WifiP2pManager类提供了很多方法允许用户通过设备的Wi-Fi模块来进行交互,比如做一些如发现,连接其他对等设备的事情。下列的方法都是可以使用的: 表格1.Wi-Fi直连技术方法

方法名详细描述

  initialize()


  通过Wi-Fi框架对应用来进行注册。这个方法必须在任何其他Wi-Fi直连方法使用之前调用。




  connect()]


  开始一个拥有特定设置的设备的点对点连接。




  cancelConnect()


  取消任何一个正在进行的点对点组的连接。




  requestConnectInfo()


  获取一个设备的连接信息。




  createGroup()


  以当前设备为组拥有者来创建一个点对点连接组。




  removeGroup()


  移除当前的点对点连接组。




  requestGroupInfo()


  获取点对点连接组的信息。




  discoverPeers()


  初始化对等设备的发现。




  requestPeers()


  获取当前发现的对等设备列表。


  WifiP2pManager的方法可以让你在一个监听器里传递参数,这样Wi-fi直连框架就可以通知给你的窗体这个方法调用的状态。可以被使用的监听器接口和使用监听器的相应的WifiP2pManager的方法的调用都将在下面这张表中有所描述:
  表格 2. Wi-Fi直连监听器方法

监听器接口相关联的方法

  WifiP2pManager.ActionListener


  connect(), cancelConnect(), createGroup(), removeGroup(), and discoverPeers()




  WifiP2pManager.ChannelListener


  initialize()




  WifiP2pManager.ConnectionInfoListener


  requestConnectInfo()




  WifiP2pManager.GroupInfoListener


  requestGroupInfo()




  WifiP2pManager.PeerListListener


  requestPeers()


  Wi-Fi直连技术的API定义了一些当特定的Wi-Fi直连事件发生时作为广播的意图,比如说当一个新的对等设备被发现,或者一个设备的Wi-Fi状态的改变。你可以在你的应用里通过创建一个处理这些意图的广播接收器来注册去接收这些意图。
  Table 3. Wi-Fi 直连意图

意图名称详细描述

  WIFI_P2P_CONNECTION_CHANGED_ACTION


  当设备的Wi-Fi连接信息状态改变时候进行广播。




  WIFI_P2P_PEERS_CHANGED_ACTION


  当调用discoverPeers()方法的时候进行广播。在你的应用里处理此意图时,你通常会调用requestPeers()去获得对等设备列表的更新。




  WIFI_P2P_STATE_CHANGED_ACTION


  当设备的Wi-Fi 直连功能打开或关闭时进行广播。




  WIFI_P2P_THIS_DEVICE_CHANGED_ACTION


  当设备的详细信息改变的时候进行广播,比如设备的名称


  

创建一个广播接收器
  一个广播接收器允许你接收由android系统发布的意图广播,这样你的应用就可以对那些你感兴趣的事件作出响应。创建一个基本的Wi-Fi直连意图使用的广播接收器的步骤如下:
  1.创建一个继承自BroadcastReceiver的类。对于类的构造,一般最常用的就是以WifiP2pManager, WifiP2pManager.Channel作为参数,同时这个广播接收器对应的窗体也将被注册进来。这个广播接收器可以像窗体发送更新或者在需要的时候可以访问Wi-Fi硬件或通信通道。
  2.在广播接收器里,处理onReceive()方法里你感兴趣的意图。执行接收到的意图的任何需要的动作。比如,广播接收器接收到一个WIFI_P2P_PEERS_CHANGED_ACTION的意图,你就要调用requestPeers()方法去获得当前发现的对等设备列表。
  下面的代码展示了怎样去创建一个典型的广播接收器。广播接收器接收一个WifiP2pManager对象和一个窗体对象作为参数然后利用这两个类去处理接收到的意图的特定的动作需求。
  



1 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
2 @SuppressLint("NewApi")
3 public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
4
5     private WifiP2pManager manager;
6     private Channel channel;
7     private WiFiDirectActivity activity;
8
9
10     public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel,
11             WiFiDirectActivity activity) {
12         super();
13         this.manager = manager;
14         this.channel = channel;
15         this.activity = activity;
16     }
17
18
19     @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
20     @SuppressLint("NewApi")
21     @Override
22     public void onReceive(Context context, Intent intent) {
23         String action = intent.getAction();
24         if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
25             int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
26             if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
27             } else {
28                 Log.d(WiFiDirectActivity.TAG, "无法使用Wifi-Direct");
29                 activity.setIsWifiP2pEnabled(false);
30                 activity.resetData();
31
32             }
33             Log.d(WiFiDirectActivity.TAG, "P2P state changed - " + state);
34         } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
35             if (manager != null) {
36                 manager.requestPeers(channel, (PeerListListener) activity.getFragmentManager()
37                         .findFragmentById(R.id.frag_list));
38             }
39             Log.d(WiFiDirectActivity.TAG, "P2P peers changed");
40         } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
41             if (manager == null) {
42                 return;
43             }
44
45             NetworkInfo networkInfo = (NetworkInfo) intent
46                     .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
47
48             if (networkInfo.isConnected()) {
49
50                 // we are connected with the other device, request connection
51                 // info to find group owner IP
52
53                 DeviceDetailFragment fragment = (DeviceDetailFragment) activity
54                         .getFragmentManager().findFragmentById(R.id.frag_detail);
55                 manager.requestConnectionInfo(channel, fragment);
56             } else {
57                 // It's a disconnect
58                 activity.resetData();
59             }
60         } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
61             DeviceListFragment fragment = (DeviceListFragment) activity.getFragmentManager()
62                     .findFragmentById(R.id.frag_list);
63             fragment.updateThisDevice((WifiP2pDevice) intent.getParcelableExtra(
64                     WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));
65
66         }
67     }
68 }
  

发现对等设备
  要发现可以使用并连接的对等设备,调用discoverPeers()方法去检测在范围内的可使用设备。这个方法的调用是异步的同时如果你创建了一个WifiP2pManager.ActionListener监听器的话你会通过onSuccess()或者onFailure()方法收到发现成功或失败的消息。
  onSuccess()方法只能通知你发现的过程是否成功而不能提供任何关于发现设备的信息:



1 manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
2     @Override
3     public void onSuccess() {
4         ...
5     }
6  
7     @Override
8     public void onFailure(int reasonCode) {
9         ...
10     }
11 });
连接到设备
  当你已经找到你要连接的设备在获得发现设备列表之后,调用connect()方法去连接指定设备。这个方法的调用需要一个包含待连接设备信息的WifiP2pConfig对象。你可以通过WifiP2pManager.ActionListener接收到连接是否成功的通知。下面的代码展示了怎样去连接一个想得到的连接:



1 WifiP2pDevice device;
2 WifiP2pConfig config = new WifiP2pConfig();
3 config.deviceAddress = device.deviceAddress;
4 manager.connect(channel, config, new ActionListener() {
5  
6     @Override
7     public void onSuccess() {
8         //success logic
9     }
10  
11     @Override
12     public void onFailure(int reason) {
13         //failure logic
14     }
15 });
  
  

创建一个Wi-Fi直连的应用
  创建一个Wi-Fi直连的应用包括创建和注册一个广播接收器,发现其他设备,连接其他设备,然后传输数据等步骤。接下来的几个部分描述了怎么去做这些工作。

初始化设置
  在使用Wi-Fi直连的API之前,你必须确保你的应用可以访问设备的硬件并且你的设备要支持Wi-Fi直连的通讯协议。如果Wi-Fi直连技术是支持的,你可以获得一个WifiP2pManager的实例对象,然后创建并注册你的广播接收器,然后开始使用Wi-Fi直连的API方法。
  1.为设备的Wi-Fi硬件获取权限并在Android的清单文件中声明你的应用正确使用的最低SDK版本:



1 <uses-sdk android:minSdkVersion="14" />
2 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
3 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
4 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
5 <uses-permission android:name="android.permission.INTERNET" />
6 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  2.在你的窗体的onCreate()方法里,获得一个WifiP2pManager的实例并调用initialize()方法通过Wi-Fi直连框架去注册你的应用。这个方法返回一个WifiP2pManager.Channel对象,是被用来连接你的应用和Wi-Fi直连框架的。你应该再创建一个以WifiP2pManager和WifiP2pManager.Channel为参数且关联你的窗体的广播接收器的实例。这样你的广播接收器就可以接收到你感兴趣的事件去通知你的窗体并更新它。它还可以让你在需要的时候操纵设备的Wi-Fi状态。



1 WifiP2pManager mManager;
2 Channel mChannel;
3 BroadcastReceiver mReceiver;
4 ...
5 @Override
6 protected void onCreate(Bundle savedInstanceState){
7     ...
8     mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
9     mChannel = mManager.initialize(this, getMainLooper(), null);
10     mReceiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
11     ...
12 }
  3.创建一个意图过滤器并把它添加在你的广播接收器需要处理的意图上。



1 IntentFilter mIntentFilter;
2 ...
3 @Override
4 protected void onCreate(Bundle savedInstanceState){
5     ...
6     mIntentFilter = new IntentFilter();
7     mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
8     mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
9     mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
10     mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
11     ...
12 }
  4.注册你的广播接收器在窗体的onResume()方法,解除注册在onPause()方法中。



1 @Override
2 protected void onResume() {
3     super.onResume();
4     registerReceiver(mReceiver, mIntentFilter);
5 }
6 /* unregister the broadcast receiver */
7 @Override
8 protected void onPause() {
9     super.onPause();
10     unregisterReceiver(mReceiver);
11 }
  当你获取到一个WifiP2pManager.Channel对象并且设置好你的广播接收器时,你的应用就可以调用Wi-Fi直连的方法并且可以接收Wi-Fi直连的意图。
  你可以现在就通过调用WifiP2pManager中的方法取实现你的应用体验Wi-Fi直连技术的特性了。
  
  下面是窗体Activity的完整代码:



  1 @SuppressLint("NewApi")
  2 public class WiFiDirectActivity extends Activity implements ChannelListener, DeviceActionListener {
  3
  4     public static final String TAG = "wifidirectdemo";
  5     private WifiP2pManager manager;
  6     private boolean isWifiP2pEnabled = false;
  7     private boolean retryChannel = false;
  8
  9     private final IntentFilter intentFilter = new IntentFilter();
10     private Channel channel;
11     private BroadcastReceiver receiver = null;
12
13     public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled) {
14         this.isWifiP2pEnabled = isWifiP2pEnabled;
15     }
16
17     @Override
18     public void onCreate(Bundle savedInstanceState) {
19         super.onCreate(savedInstanceState);
20         setContentView(R.layout.main);
21
22         // add necessary intent values to be matched.
23
24         intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
25         intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
26         intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
27         intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
28
29         manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
30         channel = manager.initialize(this, getMainLooper(), null);
31     }
32
33     /** register the BroadcastReceiver with the intent values to be matched */
34     @Override
35     public void onResume() {
36         super.onResume();
37         receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
38         registerReceiver(receiver, intentFilter);
39     }
40
41     @Override
42     public void onPause() {
43         super.onPause();
44         unregisterReceiver(receiver);
45     }
46
47     /**
48      * Remove all peers and clear all fields. This is called on
49      * BroadcastReceiver receiving a state change event.
50      */
51     public void resetData() {
52         DeviceListFragment fragmentList = (DeviceListFragment) getFragmentManager()
53                 .findFragmentById(R.id.frag_list);
54         DeviceDetailFragment fragmentDetails = (DeviceDetailFragment) getFragmentManager()
55                 .findFragmentById(R.id.frag_detail);
56         if (fragmentList != null) {
57             fragmentList.clearPeers();
58         }
59         if (fragmentDetails != null) {
60             fragmentDetails.resetViews();
61         }
62     }
63
64     @Override
65     public boolean onCreateOptionsMenu(Menu menu) {
66         MenuInflater inflater = getMenuInflater();
67         inflater.inflate(R.menu.wi_fi_direct, menu);
68         return true;
69     }
70
71     @Override
72     public boolean onOptionsItemSelected(MenuItem item) {
73         switch (item.getItemId()) {
74             case R.id.atn_direct_enable:
75                 if (manager != null && channel != null) {
76
77                     // Since this is the system wireless settings activity, it's
78                     // not going to send us a result. We will be notified by
79                     // WiFiDeviceBroadcastReceiver instead.
80
81                     startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
82                 } else {
83                     Log.e(TAG, "channel or manager is null");
84                 }
85                 return true;
86
87             case R.id.atn_direct_discover:
88                 if (!isWifiP2pEnabled) {
89                     Toast.makeText(WiFiDirectActivity.this, R.string.p2p_off_warning,
90                             Toast.LENGTH_SHORT).show();
91                     return true;
92                 }
93                 final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
94                         .findFragmentById(R.id.frag_list);
95                 fragment.onInitiateDiscovery();
96                 manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
97
98                     @Override
99                     public void onSuccess() {
100                         Toast.makeText(WiFiDirectActivity.this, "Discovery Initiated",
101                                 Toast.LENGTH_SHORT).show();
102                     }
103
104                     @Override
105                     public void onFailure(int reasonCode) {
106                         Toast.makeText(WiFiDirectActivity.this, "Discovery Failed : " + reasonCode,
107                                 Toast.LENGTH_SHORT).show();
108                     }
109                 });
110                 return true;
111             default:
112                 return super.onOptionsItemSelected(item);
113         }
114     }
115
116     @Override
117     public void showDetails(WifiP2pDevice device) {
118         DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
119                 .findFragmentById(R.id.frag_detail);
120         fragment.showDetails(device);
121
122     }
123
124     @Override
125     public void connect(WifiP2pConfig config) {
126         manager.connect(channel, config, new ActionListener() {
127
128             @Override
129             public void onSuccess() {
130                 // WiFiDirectBroadcastReceiver will notify us. Ignore for now.
131                 Log.e(TAG, "Success!");
132             }
133
134             @Override
135             public void onFailure(int reason) {
136                 Toast.makeText(WiFiDirectActivity.this, "Connect failed. Retry.",
137                         Toast.LENGTH_SHORT).show();
138             }
139         });
140     }
141
142     @Override
143     public void disconnect() {
144         final DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
145                 .findFragmentById(R.id.frag_detail);
146         fragment.resetViews();
147         manager.removeGroup(channel, new ActionListener() {
148
149             @Override
150             public void onFailure(int reasonCode) {
151                 Log.d(TAG, "Disconnect failed. Reason :" + reasonCode);
152
153             }
154
155             @Override
156             public void onSuccess() {
157                 fragment.getView().setVisibility(View.GONE);
158             }
159
160         });
161     }
162
163     @Override
164     public void onChannelDisconnected() {
165         // we will try once more
166         if (manager != null && !retryChannel) {
167             Toast.makeText(this, "Channel lost. Trying again", Toast.LENGTH_LONG).show();
168             resetData();
169             retryChannel = true;
170             manager.initialize(this, getMainLooper(), this);
171         } else {
172             Toast.makeText(this,
173                     "Severe! Channel is probably lost premanently. Try Disable/Re-Enable P2P.",
174                     Toast.LENGTH_LONG).show();
175         }
176     }
177
178     @Override
179     public void cancelDisconnect() {
180
181         if (manager != null) {
182             final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
183                     .findFragmentById(R.id.frag_list);
184             if (fragment.getDevice() == null
185                     || fragment.getDevice().status == WifiP2pDevice.CONNECTED) {
186                 disconnect();
187             } else if (fragment.getDevice().status == WifiP2pDevice.AVAILABLE
188                     || fragment.getDevice().status == WifiP2pDevice.INVITED) {
189
190                 manager.cancelConnect(channel, new ActionListener() {
191
192                     @Override
193                     public void onSuccess() {
194                         Toast.makeText(WiFiDirectActivity.this, "Aborting connection",
195                                 Toast.LENGTH_SHORT).show();
196                     }
197
198                     @Override
199                     public void onFailure(int reasonCode) {
200                         Toast.makeText(WiFiDirectActivity.this,
201                                 "Connect abort request failed. Reason Code: " + reasonCode,
202                                 Toast.LENGTH_SHORT).show();
203                     }
204                 });
205             }
206         }
207
208     }
209 }
显示设备连接的详细信息代码



  1 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
  2 @SuppressLint("NewApi")
  3 public class DeviceListFragment extends ListFragment implements PeerListListener {
  4
  5     private List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
  6     ProgressDialog progressDialog = null;
  7     View mContentView = null;
  8     private WifiP2pDevice device;
  9
10     @Override
11     public void onActivityCreated(Bundle savedInstanceState) {
12         super.onActivityCreated(savedInstanceState);
13         this.setListAdapter(new WiFiPeerListAdapter(getActivity(), R.layout.row_devices, peers));
14
15     }
16
17     @Override
18     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
19         mContentView = inflater.inflate(R.layout.device_list, null);
20         return mContentView;
21     }
22
23     public WifiP2pDevice getDevice() {
24         return device;
25     }
26
27     private static String getDeviceStatus(int deviceStatus) {
28         Log.d(WiFiDirectActivity.TAG, "Peer status :" + deviceStatus);
29         switch (deviceStatus) {
30             case WifiP2pDevice.AVAILABLE:
31                 return "available";
32             case WifiP2pDevice.INVITED:
33                 return "invited";
34             case WifiP2pDevice.CONNECTED:
35                 return "connected";
36             case WifiP2pDevice.FAILED:
37                 return "failed";
38             case WifiP2pDevice.UNAVAILABLE:
39                 return "unavailable";
40             default:
41                 return "unknow";
42
43         }
44     }
45
46     /**
47      * Initiate a connection with the peer.
48      */
49     @Override
50     public void onListItemClick(ListView l, View v, int position, long id) {
51         WifiP2pDevice device = (WifiP2pDevice) getListAdapter().getItem(position);
52         ((DeviceActionListener) getActivity()).showDetails(device);
53     }
54
55     /**
56      * Array adapter for ListFragment that maintains WifiP2pDevice list.
57      */
58     private class WiFiPeerListAdapter extends ArrayAdapter<WifiP2pDevice> {
59
60         private List<WifiP2pDevice> items;
61
62         public WiFiPeerListAdapter(Context context, int textViewResourceId,
63                 List<WifiP2pDevice> objects) {
64             super(context, textViewResourceId, objects);
65             items = objects;
66
67         }
68
69         @Override
70         public View getView(int position, View convertView, ViewGroup parent) {
71             View v = convertView;
72             if (v == null) {
73                 LayoutInflater vi = (LayoutInflater) getActivity().getSystemService(
74                         Context.LAYOUT_INFLATER_SERVICE);
75                 v = vi.inflate(R.layout.row_devices, null);
76             }
77             WifiP2pDevice device = items.get(position);
78             if (device != null) {
79                 TextView top = (TextView) v.findViewById(R.id.device_name);
80                 TextView bottom = (TextView) v.findViewById(R.id.device_details);
81                 if (top != null) {
82                     top.setText(device.deviceName);
83                 }
84                 if (bottom != null) {
85                     bottom.setText(getDeviceStatus(device.status));
86                 }
87             }
88
89             return v;
90
91         }
92     }
93
94     public void updateThisDevice(WifiP2pDevice device) {
95         this.device = device;
96         TextView view = (TextView) mContentView.findViewById(R.id.my_name);
97         view.setText(device.deviceName);
98         view = (TextView) mContentView.findViewById(R.id.my_status);
99         view.setText(getDeviceStatus(device.status));
100     }
101     
102     @Override
103     public void onPeersAvailable(WifiP2pDeviceList peerList) {
104         if (progressDialog != null && progressDialog.isShowing()) {
105             progressDialog.dismiss();
106         }
107         peers.clear();
108         peers.addAll(peerList.getDeviceList());
109      
110         if (peers.size() == 0) {
111             Log.d(WiFiDirectActivity.TAG, "size==0");
112             return;
113         }
114
115     }
116
117     public void clearPeers() {
118         peers.clear();
119         ((WiFiPeerListAdapter) getListAdapter()).notifyDataSetChanged();
120     }
121
122     public void onInitiateDiscovery() {
123         if (progressDialog != null && progressDialog.isShowing()) {
124             progressDialog.dismiss();
125         }
126         progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel", "finding peers", true,
127                 true, new DialogInterface.OnCancelListener() {
128
129                     @Override
130                     public void onCancel(DialogInterface dialog) {
131                        
132                     }
133                 });
134     }
135
136     public interface DeviceActionListener {
137
138         void showDetails(WifiP2pDevice device);
139
140         void cancelDisconnect();
141
142         void connect(WifiP2pConfig config);
143
144         void disconnect();
145     }
146
147 }
  

数据传输
  一旦连接已经建立,你可以通过套接字来进行数据的传输。基本的数据传输步骤如下:
  1.创建一个ServerSocket对象。这个服务端套接字对象等待一个来自指定地址和端口的客户端的连接且阻塞线程直到连接发生,所以把它建立在一个后台线程里。
  2.创建一个客户端Socket.这个客户端套接字对象使用指定ip地址和端口去连接服务端设备。
  3.服务端等待客户端的连接(使用accept()方法)。这个调用阻塞服务端线程直到客户端连接上,所以叫这个过程一个新的线程。当连接建立时,服务端可以接受来自客户端的数据。执行关于数据的任何动作,比如保存数据或者展示给用户。
  



1      @Override
2         protected String doInBackground(Void... params) {
3             try {
4                 ServerSocket serverSocket = new ServerSocket(8888);
5                 //服务器端口号
6                 Log.d(WiFiDirectActivity.TAG, "Server: Socket opened");
7                 Socket client = serverSocket.accept();
8                 //客户端绑定服务器端口
9                 //!!!!!!!!!!使用accept方法等待客户机发送数据
10                 Log.d(WiFiDirectActivity.TAG, "Server: connection done");
11                 
12                 
13                 final File f = new File(Environment.getExternalStorageDirectory() + "/"
14                         + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
15                         + ".jpg");
16
17                 File dirs = new File(f.getParent());
18                 if (!dirs.exists())
19                     dirs.mkdirs();
20                 f.createNewFile();
21
22                 Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
23                 InputStream inputstream = client.getInputStream();
24                 copyFile(inputstream, new FileOutputStream(f));
25                 serverSocket.close();
26                 return f.getAbsolutePath();
27             } catch (IOException e) {
28                 Log.e(WiFiDirectActivity.TAG, e.getMessage());
29                 return null;
30             }
31         }
  4.服务端与客户端,官方demo只给出了客户端向服务端发送数据的方式。



1 @Override
2     public void onConnectionInfoAvailable(final WifiP2pInfo info) {
3         if (progressDialog != null && progressDialog.isShowing()) {
4             progressDialog.dismiss();
5         }
6         this.info = info;
7         this.getView().setVisibility(View.VISIBLE);
8
9         // The owner IP is now known.
10         TextView view = (TextView) mContentView.findViewById(R.id.group_owner);
11         view.setText(getResources().getString(R.string.group_owner_text)
12                 + ((info.isGroupOwner == true) ? getResources().getString(R.string.yes)
13                         : getResources().getString(R.string.no)));
14
15         // InetAddress from WifiP2pInfo struct.
16         view = (TextView) mContentView.findViewById(R.id.device_info);
17         view.setText("群主IP - " + info.groupOwnerAddress.getHostAddress());  
18
19         // After the group negotiation, we assign the group owner as the file
20         // server. The file server is single threaded, single connection server
21         // socket.
22         if (info.groupFormed && info.isGroupOwner) {      
23             new FileServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text))
24                  .execute();
25         } else if (info.groupFormed) {
26             mContentView.findViewById(R.id.btn_start_client).setVisibility(View.VISIBLE);
27             ((TextView) mContentView.findViewById(R.id.status_text)).setText(getResources()
28                     .getString(R.string.client_text));
29         }
30         
31         // hide the connect button
32         mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE);
33     }
  
  完整代码如下:



  1 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
  2 @SuppressLint("NewApi")
  3 public class DeviceDetailFragment extends Fragment implements ConnectionInfoListener {
  4
  5     protected static final int CHOOSE_FILE_RESULT_CODE = 20;
  6     private View mContentView = null;
  7     private WifiP2pDevice device;
  8     private WifiP2pInfo info;
  9     ProgressDialog progressDialog = null;
10
11     @Override
12     public void onActivityCreated(Bundle savedInstanceState) {
13         super.onActivityCreated(savedInstanceState);
14     }
15
16     @Override
17     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
18
19         mContentView = inflater.inflate(R.layout.device_detail, null);
20         mContentView.findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() {
21
22             @Override
23             public void onClick(View v) {
24                 WifiP2pConfig config = new WifiP2pConfig();
25                 config.deviceAddress = device.deviceAddress;
26                 config.wps.setup = WpsInfo.PBC;
27                 if (progressDialog != null && progressDialog.isShowing()) {
28                     progressDialog.dismiss();
29                 }
30                 progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel",
31                         "Connecting to :" + device.deviceAddress, true, true);
32             }
33         });
34
35         mContentView.findViewById(R.id.btn_disconnect).setOnClickListener(
36                 new View.OnClickListener() {
37
38                     @Override
39                     public void onClick(View v) {
40                         ((DeviceActionListener) getActivity()).disconnect();
41                     }
42                 });
43
44         mContentView.findViewById(R.id.btn_start_client).setOnClickListener(
45                 new View.OnClickListener() {
46
47                     @Override
48                     public void onClick(View v) {
49                         Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
50                         intent.setType("image/*");
51                         startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE);
52                     }
53                 });
54
55         return mContentView;
56     }
57
58     @Override
59     public void onActivityResult(int requestCode, int resultCode, Intent data) {
60
61         // User has picked an image. Transfer it to group owner i.e peer using
62         // FileTransferService.
63         Uri uri = data.getData();
64         TextView statusText = (TextView) mContentView.findViewById(R.id.status_text);
65         statusText.setText("Sending: " + uri);
66         Log.d(WiFiDirectActivity.TAG, "Intent----------- " + uri);
67         Intent serviceIntent = new Intent(getActivity(), FileTransferService.class);
68         serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
69         serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
70         serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS,
71                 info.groupOwnerAddress.getHostAddress());
72         serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8888);
73         getActivity().startService(serviceIntent);
74     }
75
76     @Override
77     public void onConnectionInfoAvailable(final WifiP2pInfo info) {
78         if (progressDialog != null && progressDialog.isShowing()) {
79             progressDialog.dismiss();
80         }
81         this.info = info;
82         this.getView().setVisibility(View.VISIBLE);
83
84         // The owner IP is now known.
85         TextView view = (TextView) mContentView.findViewById(R.id.group_owner);
86         view.setText(getResources().getString(R.string.group_owner_text)
87                 + ((info.isGroupOwner == true) ? getResources().getString(R.string.yes)
88                         : getResources().getString(R.string.no)));
89
90         // InetAddress from WifiP2pInfo struct.
91         view = (TextView) mContentView.findViewById(R.id.device_info);
92         view.setText("群主IP - " + info.groupOwnerAddress.getHostAddress());  
93
94         // After the group negotiation, we assign the group owner as the file
95         // server. The file server is single threaded, single connection server
96         // socket.
97         if (info.groupFormed && info.isGroupOwner) {      
98             new FileServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text))
99                  .execute();
100         } else if (info.groupFormed) {
101             mContentView.findViewById(R.id.btn_start_client).setVisibility(View.VISIBLE);
102             ((TextView) mContentView.findViewById(R.id.status_text)).setText(getResources()
103                     .getString(R.string.client_text));
104         }
105         
106         // hide the connect button
107         mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE);
108     }
109
110     /**
111      * Updates the UI with device data
112      *
113      * @param device the device to be displayed
114      */
115     public void showDetails(WifiP2pDevice device) {
116         this.device = device;
117         this.getView().setVisibility(View.VISIBLE);
118         TextView view = (TextView) mContentView.findViewById(R.id.device_address);
119         view.setText(device.deviceAddress);
120         view = (TextView) mContentView.findViewById(R.id.device_info);
121         view.setText(device.toString());
122
123     }
124
125     /**
126      * Clears the UI fields after a disconnect or direct mode disable operation.
127      */
128     public void resetViews() {
129         mContentView.findViewById(R.id.btn_connect).setVisibility(View.VISIBLE);
130         TextView view = (TextView) mContentView.findViewById(R.id.device_address);
131         view.setText(R.string.empty);
132         view = (TextView) mContentView.findViewById(R.id.device_info);
133         view.setText(R.string.empty);
134         view = (TextView) mContentView.findViewById(R.id.group_owner);
135         view.setText(R.string.empty);
136         view = (TextView) mContentView.findViewById(R.id.status_text);
137         view.setText(R.string.empty);
138         mContentView.findViewById(R.id.btn_start_client).setVisibility(View.GONE);
139         this.getView().setVisibility(View.GONE);
140     }
141
142     public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
143
144         private Context context;
145         private TextView statusText;
146
147         public FileServerAsyncTask(Context context, View statusText) {
148             this.context = context;
149             this.statusText = (TextView) statusText;
150         }
151
152         @Override
153         protected String doInBackground(Void... params) {
154             try {
155                 ServerSocket serverSocket = new ServerSocket(8888);
156                 //服务器端口号
157                 Log.d(WiFiDirectActivity.TAG, "Server: Socket opened");
158                 Socket client = serverSocket.accept();
159                 //客户端绑定服务器端
160                 //!!!!!!!!!!使用accept方法等待客户机发送数据
161                 Log.d(WiFiDirectActivity.TAG, "Server: connection done");
162                 
163                 
164                 final File f = new File(Environment.getExternalStorageDirectory() + "/"
165                         + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
166                         + ".jpg");
167
168                 File dirs = new File(f.getParent());
169                 if (!dirs.exists())
170                     dirs.mkdirs();
171                 f.createNewFile();
172
173                 Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
174                 InputStream inputstream = client.getInputStream();
175                 copyFile(inputstream, new FileOutputStream(f));
176                 serverSocket.close();
177                 return f.getAbsolutePath();
178             } catch (IOException e) {
179                 Log.e(WiFiDirectActivity.TAG, e.getMessage());
180                 return null;
181             }
182         }
183
184         @Override
185         protected void onPostExecute(String result) {
186             if (result != null) {
187                 statusText.setText("File copied - " + result);
188                 Intent intent = new Intent();
189                 intent.setAction(android.content.Intent.ACTION_VIEW);
190                 intent.setDataAndType(Uri.parse("file://" + result), "image/*");
191                 context.startActivity(intent);
192             }
193
194         }
195
196         @Override
197         protected void onPreExecute() {
198             statusText.setText("Opening a server socket");
199         }
200
201     }
202
203     public static boolean copyFile(InputStream inputStream, OutputStream out) {
204         byte buf[] = new byte[1024];
205         int len;
206         try {
207             while ((len = inputStream.read(buf)) != -1) {
208                 out.write(buf, 0, len);
209
210             }
211             out.close();
212             inputStream.close();
213         } catch (IOException e) {
214             Log.d(WiFiDirectActivity.TAG, e.toString());
215             return false;
216         }
217         return true;
218     }
219
220 }
  文件传输代码如下:



1 public class FileTransferService extends IntentService {
2
3     private static final int SOCKET_TIMEOUT = 5000;
4     public static final String ACTION_SEND_FILE = "com.example.android.wifidirect.SEND_FILE";
5     public static final String EXTRAS_FILE_PATH = "file_url";
6     public static final String EXTRAS_GROUP_OWNER_ADDRESS = "go_host";
7     public static final String EXTRAS_GROUP_OWNER_PORT = "go_port";
8
9     public FileTransferService(String name) {
10         super(name);
11     }
12
13     public FileTransferService() {
14         super("FileTransferService");
15     }
16
17     @Override
18     protected void onHandleIntent(Intent intent) {
19
20         Context context = getApplicationContext();
21         if (intent.getAction().equals(ACTION_SEND_FILE)) {
22             String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);
23             String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS);
24             Socket socket = new Socket();
25             int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
26         
27             try {
28                 Log.d(WiFiDirectActivity.TAG, "Opening client socket - ");
29                 socket.bind(null);
30                 socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
31
32                 Log.d(WiFiDirectActivity.TAG, "Client socket - " + socket.isConnected());
33                 OutputStream stream = socket.getOutputStream();
34                 ContentResolver cr = context.getContentResolver();
35                 InputStream is = null;
36                 try {
37                     is = cr.openInputStream(Uri.parse(fileUri));
38                 } catch (FileNotFoundException e) {
39                     Log.d(WiFiDirectActivity.TAG, e.toString());
40                 }
41                 DeviceDetailFragment.copyFile(is, stream);
42                 Log.d(WiFiDirectActivity.TAG, "Client: Data written");
43             } catch (IOException e) {
44                 Log.e(WiFiDirectActivity.TAG, e.getMessage());
45             } finally {
46                 if (socket != null) {
47                     if (socket.isConnected()) {
48                         try {
49                             socket.close();
50                         } catch (IOException e) {
51                             // Give up
52                             e.printStackTrace();
53                         }
54                     }
55                 }
56             }
57
58         }
59         
60     }
61 }
  
  
  
  


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-120986-1-1.html 上篇帖子: android 指定wifi热点自动连接 下篇帖子: wifi 定位
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表