但是如果可以直接利用wifi direct的方式連接的話,不需要連接AP就可以直接溝通了。
在MainActivity.java中,透過implement WifiP2pManager.PeerListListener, 以及WifiP2pManager.ConnectionInfoListener來做。
這個寫法是直接搜尋附近最近一個可以連線的裝置,找到之後會自動連線。
完整程式碼 MainActivity.java:
import android.annotation.SuppressLint; import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.NetworkInfo; import android.net.wifi.WifiManager; import android.net.wifi.WpsInfo; import android.net.wifi.p2p.WifiP2pConfig; import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pDeviceList; import android.net.wifi.p2p.WifiP2pGroup; import android.net.wifi.p2p.WifiP2pInfo; import android.net.wifi.p2p.WifiP2pManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity implements WifiP2pManager.PeerListListener, WifiP2pManager.ConnectionInfoListener { private final String TAG = "MainActivity"; private boolean isDeviceFound = false; private TextView tvMacAddress, tvConnectDevice, tvConnectStatus; private WifiP2pManager.Channel mChannel; private WifiP2pManager mWifiP2pManager; private final IntentFilter intentFilter = new IntentFilter(); private Listpeers = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // find view by id tvMacAddress = (TextView)findViewById(R.id.id_tvMacAddress); tvConnectDevice = (TextView)findViewById(R.id.id_tvConnectDevice); tvConnectStatus = (TextView)findViewById(R.id.id_tvConnectStatus); disconnectFunc(); WifiManager mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); BluetoothAdapter myDevice = BluetoothAdapter.getDefaultAdapter(); if (mWifiManager != null) { // Turn on wifi mWifiManager.setWifiEnabled(true); // get my device and mac address tvMacAddress.setText(myDevice.getName() + ", MAC[" + mWifiManager.getConnectionInfo().getMacAddress() + "]"); } // setup wifi p2p intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); registerReceiver(mReceiver, intentFilter); mWifiP2pManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); mChannel = mWifiP2pManager.initialize(this, getMainLooper(), null); mWifiP2pManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { Log.d(TAG,"discoverPeers onSuccess"); } @Override public void onFailure(int reasonCode) { Log.d(TAG,"discoverPeers onFailure"); } }); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { Log.d(TAG,"WIFI_P2P_STATE_CHANGED_ACTION"); } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { Log.d(TAG,"WIFI_P2P_PEERS_CHANGED_ACTION"); if (mWifiP2pManager != null) { mWifiP2pManager.requestPeers(mChannel, MainActivity.this); } } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { Log.d(TAG,"WIFI_P2P_CONNECTION_CHANGED_ACTION"); if (mWifiP2pManager == null) { return; } NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); if (networkInfo.isConnected()) { mWifiP2pManager.requestConnectionInfo(mChannel, MainActivity.this); } } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { Log.d(TAG,"WIFI_P2P_THIS_DEVICE_CHANGED_ACTION"); } } }; // search available devices and auto connect first one @Override public void onPeersAvailable(WifiP2pDeviceList peerList) { peers.clear(); peers.addAll(peerList.getDeviceList()); String[] peersMacAddress, peersDeviceName; if (peers.size() == 0) { Log.d(TAG, "No devices found"); tvConnectStatus.setText("no connected"); peersMacAddress = new String[1]; peersMacAddress[0]="No Devices found"; peersDeviceName = new String[1]; peersDeviceName[0]="No Devices found"; } else{ peersMacAddress = new String[peers.size()]; peersDeviceName = new String[peers.size()]; int i=0, j=0; for(WifiP2pDevice device: peers){ peersDeviceName[i++] = device.deviceName; peersMacAddress[j++] = device.deviceAddress; // find the first device and auto connect if(device.deviceAddress.equals(peersMacAddress[0])){ tvConnectDevice.setText(peersDeviceName[0] + ", MAC[" + peersMacAddress[0] + "]"); if(!isDeviceFound){ connectFunc(); isDeviceFound = true; } } } } } // check connect status @Override public void onConnectionInfoAvailable(WifiP2pInfo info) { tvConnectDevice.setText("Stop Searching"); tvConnectStatus.setText("Device already connected"); } private void connectFunc(){ Log.d(TAG, "connectFunc"); WifiP2pDevice device = peers.get(0); WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = device.deviceAddress; config.wps.setup = WpsInfo.PBC; mWifiP2pManager.connect(mChannel, config, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { Log.d(TAG,"connect success"); tvConnectStatus.setText("device connected"); } @Override public void onFailure(int reason) { Log.d(TAG,"connect fail"); } }); } private void disconnectFunc(){ Log.d(TAG, "disconnectFunc"); if (mWifiP2pManager != null && mChannel != null) { mWifiP2pManager.requestGroupInfo(mChannel, new WifiP2pManager.GroupInfoListener() { @Override public void onGroupInfoAvailable(WifiP2pGroup group) { if (group != null && mWifiP2pManager != null && mChannel != null && group.isGroupOwner()) { mWifiP2pManager.removeGroup(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { Log.d(TAG, "removeGroup onSuccess -"); } @Override public void onFailure(int reason) { Log.d(TAG, "removeGroup onFailure -" + reason); } }); } } }); } } }
補上xml:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.chris.myapplication.MainActivity"> <TextView android:id="@+id/id_tvMyDevice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="My Device:" app:layout_constraintStart_toStartOf="parent" /> <TextView android:id="@+id/id_tvMacAddress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="My Mac Address" app:layout_constraintTop_toBottomOf="@+id/id_tvMyDevice" /> <TextView android:id="@+id/id_tvDeviceFound" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="Device Found:" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/id_tvMacAddress" /> <TextView android:id="@+id/id_tvConnectDevice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Searching..." app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/id_tvDeviceFound" /> <TextView android:id="@+id/id_tvConnectStatus" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="no connected" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/id_tvConnectDevice" /> </android.support.constraint.ConstraintLayout>
在AndroidManifest.xml加入權限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
連線成功之後,接下來有時間再來寫加入UDP傳輸試試看。
END
沒有留言:
張貼留言