WIFI Direct开发实例演示 图片看不了?点击切换HTTP 返回上层
实例 WIFIDirectDemo 改编 Android SDK 提供的实例,演示了通过 WIFI 搜寻连接点,建立连接,并进行数据传输的过程。
该实例包含 5 个类,说明说下:
该实例的运行效果如图 1 所示。

图 1 实例WIFIDirectDemo的运行效果
WIFIDirectDemo 的 AndroidManifest.xml 文件内容如下:
WIFIDirectDemoActivity.java 的代码如下:
WiFiDirectBroadcastReceiver.java 的代码如下:
DeviceListFragment.java 的代码如下:
FileTransferService.java 的代码如下:
该实例包含 5 个类,说明说下:
- WIFIDirectDemoActivity:用于注册 BroadcastReceiver,处理 UI,并管理连接点的生命周期。
- WiFiDirectBroadcastReceiver:用于接收与 WIFI Direct 功能相关的 Intent。
- DeviceListFragment:用于显示可以连接点列表及其状态。
- FileTransferService:通过 TCP 协议在客户端与服务器之间进行文件传输的 IntentService。
- IntentService:Sevice 的子类,用于处理异步请求。
该实例的运行效果如图 1 所示。

图 1 实例WIFIDirectDemo的运行效果
WIFIDirectDemo 的 AndroidManifest.xml 文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <?xml version= "1.0" encoding= "utf-8" ?> <manifest xmlns:android= "http://schemas.android.com/apk/res/android" package= "introduction.android.wifidirectdemo" > <uses-sdk android:minSdkVersion= "14" /> <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.READ_CONTACTS" /> <uses-permission android: name = "android.permission.WRITE_EXTERNAL_STORAGE" /> <! --Market filtering --> <uses-feature android: name = "android.hardware.wifi.direct" android:required= "true" /> <application android:allowBackup= "true" android:icon= "@mipmap/ic_launcher" android:label= "@string/app_name" android:roundIcon= "@mipmap/ic_launcher_round" android:supportsRtl= "true" android:theme= "@style/AppTheme" > <activity android: name = ".WIFIDirectDemoActivity" > <intent-filter> < action android: name = "android.intent.action.MAIN" /> <category android: name = "android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | package introduction.android.wifidirectdemo; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.wifi.p2p.WifiP2pConfig; import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pManager; import android.net.wifi.p2p.WifiP2pManager.ActionListener; import android.net.wifi.p2p.WifiP2pManager.Channel; import android.net.wifi.p2p.WifiP2pManager.ChannelListener; import android.os.Bundle; import android.provider.Settings; import android.util.Log; import android. view .Menu; import android. view .MenuInflater; import android. view .MenuItem; import android. view . View ; import android.widget.Toast; public class WIFIDirectDemoActivity extends Activity implements ChannelListener, DeviceListFragment.WiFiPeerListAdapter.DeviceActionListener { public static final String TAG = "wifidirectdemo" ; private WifiP2pManager manager; private boolean isWifiP2pEnabled = false ; private boolean retryChannel = false ; private final IntentFilter intentFilter = new IntentFilter(); private Channel channel; private BroadcastReceiver receiver = null ; public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled) { this.isWifiP2pEnabled = isWifiP2pEnabled; } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // add necessary intent values to be matched. intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTI0N); intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTI0N); intentFilter.addAction(WifiP2pManager.WIFI_P2P_C0NNECTI0N_CHANGED_ACTI0N); intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTI0N); manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); channel = manager.initialize(this, getMainLooper(), null ); } /** * register the BroadcastReceiver with the intent values to be matched */ public void onResume() { super.onResume(); receiver = new WiFiDirectBroadcastReceiver(manager, channel, this); registerReceiver(receiver, intentFilter); } public void onPause() { super.onPause(); unregisterReceiver(receiver); } /* *Remove all peers and clear all fields.This is called on *BroadcastReceiver receiving a state change event. */ public void resetData() { DeviceListFragment fragmentList = (DeviceListFragment) getFragmentManager() .findFragmentById(R.id.frag_list); DeviceDetailFragment1 fragmentDetails = (DeviceDetailFragment1) getFragmentManager().findFragmentById(R.id.frag_detail); if (fragmentList != null ) { fragmentList.clearPeers(); } if (fragmentDetails != null ) { fragmentDetails.resetViews(); } } public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.action_items, menu); return true ; } public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.atn_direct_enable: if (manager != null && channel != null ) { startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS)); } else { Log.e(TAG, "channel or manager is null" ); } return true ; case R.id.atn_direct_discover: if (!isWifiP2pEnabled) { Toast.makeText(WIFIDirectDemoActivity.this, R.string.p2p_off_warning, Toast.LENGTHJSHORT).show(); return true ; } final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager().findFragmentByld(R.id.frag_list); fragment.onInitiateDiscovery(); manager.discoverPeers(channel, new WifiP2pManager.ActionListener() { public void onSuccess() { Toast.makeText(WIFIDirectDemoActivity.this, "Discovery Initiated" , Toast.LENGTH_SHORT).show(); } public void onFailure( int reasonCode) { Toast.makeText(WIFIDirectDemoActivity.this, "Discovery Failed " + reasonCode, Toast.LENGTH_SHORT).show(); } }); return true ; default : return super.onOptionsItemSelected(item); } } public void showDetails(WifiP2pDevice device) { DeviceDetailFragmentl fragment = (DeviceDetailFragmentl) getFragmentManager().findFragmentById(R.id.frag_detail); fragment.showDetails(device); } public void connect (WifiP2pConfig config) { manager. connect (channel, config, new ActionListener() { public void onSuccess() { // WiFiDirectBroadcastReceiver will notify us. Ignore for now. } public void onFailure( int reason) { Toast.makeText(WIFIDirectDemoActivity.this, "Connect failed. Retry." , Toast.LENGTH_SHORT).show(); } }); } public void disconnect() { final DeviceDetailFragmentl fragment = (DeviceDetailFragmentl) getFragmentManager().findFragmentById(R.id.frag_detail); fragment.resetViews(); manager.removeGroup(channel, new ActionListener() { public void onFailure( int reasonCode) { Log.d(TAG, "Disconnect failed. Reason :" + reasonCode); } public void onSuccess() { fragment.getView().setVisibility( View .GONE); } }); } public void onChannelDisconnected() { if (manager != null && !retryChannel) { Toast.makeText(this, "Channel lost. Trying again" , Toast.LENGTH_LONG).show(); resetData(); retryChannel = true ; manager.initialize(this, getMainLooper(), this); } else { Toast.makeText(this, "Severe! Channel is probably lost premanently. Try Disable/Re-Enable P2P." ,Toast.LENGTH_LONG).show(); } } public void cancelDisconnect() { if (manager != null ) { final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager().findFragmentById(R.id.frag_list); if (fragment.getDevice() == null || fragment.getDevice().status == WifiP2pDevice.CONNECTED) { disconnect(); } else if (fragment.getDevice().status == WifiP2pDevice.AVAILABLE || fragment.getDevice().status == WifiP2pDevice.INVITED) { manager.cancelConnect(channel, new ActionListener() { public void onSuccess() { Toast.makeText(WIFIDirectDemoActivity.this, "Aborting connection" , Toast.LENGTH_SHORT).show(); } public void onFailure( int reasonCode) { Toast.makeText(WIFIDirectDemoActivity.this, "Connect abort request failed. Reason Code: " + reasonCode, Toast.LENGTH_SHORT).show(); } }); } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | package introduction.android.wifidirectdemo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.net.NetworkInfo; import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pManager; import android.net.wifi.p2p.WifiP2pManager.Channel; import android.net.wifi.p2p.WifiP2pManager.PeerListListener; import android.util.Log; public class WiFiDirectBroadcastReceiver extends BroadcastReceiver { private WifiP2pManager manager; private Channel channel; private WIFIDirectDemoActivity activity; public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel, WIFIDirectDemoActivity wifiDirectDemoActivity) { super(); this.manager = manager; this.channel = channel; this.activity = wifiDirectDemoActivity; } @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals( action )) { // UI update to indicate wifi p2p status. int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1); if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) { // Wifi Direct mode is enabled activity.setlsWifiP2pEnabled ( true ) ; } else { activity.setIsWifiP2pEnabled( false ); activity.resetData(); } Log.d(WIFIDirectDemoActivity.TAG, "P2P state changed - " + state); } else 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 (manager != null ) { manager.requestPeers(channel, (PeerListListener) activity.getFragmentManager().findFragmentById(R.id.frag_list)); Log.d(WIFIDirectDemoActivity.TAG, "P2P peers changed" ); } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals( action )) { if (manager == null ) { return ; } NetworkInfo networkInfo = (NetworkInfo) intent .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); if (networkInfo.isConnected()) { // we are connected with the other device, request connection // info to find group owner IP DeviceDetailFragment1 fragment = (DeviceDetailFragmentl) activity.getFragmentManager().findFragmentById(R.id.frag_detail); manager.requestConnectionlnfo(channel, fragment); } else { // It's a disconnect activity.resetData(); } } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals( action )){ DeviceListFragment fragment = (DeviceListFragment) activity.getFragmentManager() .findFragmentById(R.id.frag_list); fragment.updateThisDevice((WifiP2pDevice) intent.getParcelableExtra( WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | package introduction.android.wifidirectdemo; import android.app.ListFragment; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.net.wifi.p2p.WifiP2pConfig; import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pDeviceList; import android.net.wifi.p2p.WifiP2pManager.PeerListListener; import android.os.Bundle; import android.util.Log; import android. view .LayoutInflater; import android. view . View ; import android. view .ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; import java.util.ArrayList; import java.util.List; public class DeviceListFragment extends ListFragment implements PeerListListener { private List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>(); ProgressDialog progressDialog = null ; View mContentView = null ; private WifiP2pDevice device; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); this.setListAdapter(new WiFiPeerListAdapter(getActivity(), R.layout.row_devices, peers)); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mContentView = inflater.inflate(R.layout.device_list, null ); return mContentView; } /* return this device */ public WifiP2pDevice getDevice() { return device; } private static String getDeviceStatus( int deviceStatus) { Log.d(WIFIDirectDemoActivity.TAG, "Peer status :" + deviceStatus); switch (deviceStatus) { case WifiP2pDevice.AVAILABLE: return "Available" ; case WifiP2pDevice.INVITED: return "Invited" ; case WifiP2pDevice.CONNECTED: return "Connected" ; case WifiP2pDevice.FAILED: return "Failed" ; case WifiP2pDevice.UNAVAILABLE: return "Unavailable" ; default : return "Unknown" ; } } /** * Initiate a connection with the peer. */ @Override public void onListItemClick(ListView l, View v, int position, long id) { WifiP2pDevice device = (WifiP2pDevice) getListAdapter().getItem(position); ((DeviceActionListener) getActivity()).showDetails(device); } /* Array adapter for ListFragment that maintains WifiP2pDevice list. */ public class WiFiPeerListAdapter extends ArrayAdapter<WifiP2pDevice> { private List<WifiP2pDevice> items; public WiFiPeerListAdapter(Context context, int textViewResourceId, List<WifiP2pDevice> objects) { super(context, textViewResourceId, objects); items = objects; } @Override public View getView( int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null ) { LayoutInflater vi = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.row_devices, null ); } WifiP2pDevice device = items.get(position); if (device != null ) { TextView top = (TextView) v.findViewById(R.id.device_name); TextView bottom = (TextView) v.findViewById(R.id.device_details); if ( top != null ) { top .setText(device.deviceName); } if (bottom != null ) { bottom.setText(getDeviceStatus(device.status)); } } return v; } public void updateThisDevice(WifiP2pDevice device) { this.device = device; TextView view = (TextView) mContentView.findViewById(R.id.my_name); view .setText(device.deviceName); view = (TextView) mContentView.findViewById(R.id.my_status); view .setText(getDeviceStatus(device.status)); } public void onPeersAvailable(WifiP2pDeviceList peerList) { if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } peers.clear(); peers.addAll(peerList.getDeviceList()); ((WiFiPeerListAdapter) getListAdapter()).notifyDataSetChanged(); if (peers. size () == 0) { Log.d(WIFIDirectDemoActivity.TAG, "No devices found" ); return ; } } public void clearPeers() { peers.clear(); ((WiFiPeerListAdapter) getListAdapter()).notifyDataSetChanged(); } public void onInitiateDiscovery() { if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel" , true , true , new DialogInterface.OnCancelListener() { public void onCancel(DialogInterface dialog) { } }); } public interface DeviceActionListener { void showDetails(WifiP2pDevice device); void cancelDisconnect(); void connect (WifiP2pConfig config); void disconnect(); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | package introduction.android.wifidirectdemo; import android.app.IntentService; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.util.Log; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; public class FileTransferService extends IntentService { private static final int SOCKET_TIMEOUT = 5000; public static final String ACTION_SEND_FILE = "com.example.android.wifidirect.SEND_FILE" public static final String EXTRAS_FILE_PATH = "file_url" ; public static final String EXTRAS_GROUP_OWNER_ADDRESS = "go_host" ; public static final String EXTRAS_GROUP_OWNER_PORT = "go_port" ; public FileTransferService(String name ) { super( name ); } public FileTransferService() { super( "FileTransferService" ); } @Override protected void onHandleIntent(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 { Log.d(WIFIDirectDemoActivity.TAG, "Opening client socket - " ); socket.bind( null ); socket. connect ((new InetSocketAddress(host, port)), SOCKET_TIMEOUT); Log.d(WIFIDirectDemoActivity.TAG, "Client socket - " + socket.isConnected()) OutputStream stream = socket.getOutputStream(); ContentResolver cr = context.getContentResolver(); InputStream is = null ; try { is = cr.openInputStream(Uri.parse(fileUri)); } catch (FileNotFoundException e) { Log.d(WIFIDirectDemoActivity.TAG, e.toString()); } DeviceDetailFragment1.copyFile( is , stream); Log.d(WIFIDirectDemoActivity.TAG, "Client: Data written" ); } catch (IOException e) { Log.e(WIFIDirectDemoActivity.TAG, e.getMessage()); } finally { if (socket != null ) { if (socket.isConnected()) { try { socket. close (); } catch (IOException e) { // Give up e.printStackTrace(); } } } } } } } |