WiFi P2P是指通过WiFi直接连接两台设备之间的无线点对点通信,不需要通过路由器或者互联网。这种技术被广泛应用于移动设备之间的文件共享、游戏联机、音乐播放等应用场景中。

WiFi P2P的优点在于可以在没有网络的情况下建立设备之间的连接,同时具有高速和低延迟的特点。它还支持多种语言编程接口,并且使用起来非常简单。

在Android中,WiFi P2P可以通过WifiP2pManager类进行实现,它提供了许多方法来扫描可用设备、建立P2P连接并传输数据等功能。开发者可以通过这些方法来实现设备之间的文件传输等操作。

WiFi和蓝牙是两种不同类型的无线通信技术,在许多方面都有不同的特点和用途。

以下是一些常见的WiFi和蓝牙的比较:

传输速率:WiFi传输速度更快,可以达到几百兆比特每秒,而蓝牙通常只能达到几兆比特每秒。

距离限制:WiFi的覆盖范围通常更大,可以在较长的距离内进行通信,而蓝牙的覆盖范围通常比较小,仅能在短距离内通信。

电池寿命:由于WiFi的功率更大,因此它通常消耗更多的电池生命,而蓝牙通常需要更少的功率,因此它通常耗电更少。

下面是使用Wifi P2P传输文件的基本代码示例,您可以根据需要进行调整:

1. 添加权限和依赖项

在AndroidManifest.xml中添加以下权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

在build.gradle文件中添加以下依赖项:

implementation 'com.android.support:appcompat-v7:28.0.0'

implementation 'com.android.support:design:28.0.0'

implementation 'com.android.support:recyclerview-v7:28.0.0'

implementation 'com.android.support:cardview-v7:28.0.0'

2. 设置布局文件

在布局文件中添加以下代码:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:textColor="#000000" />

    <Button
        android:id="@+id/button_search"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="搜索可用设备" />

    <ListView
        android:id="@+id/list_devices"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button_search"
        android:layout_marginTop="20dp"
        android:visibility="gone" />

</RelativeLayout>

3. 创建WifiP2pManager和WifiP2pManager.Channel对象

在Activity中定义以下变量:

private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private BroadcastReceiver mReceiver;
private IntentFilter mIntentFilter;
private List<WifiP2pDevice> peers = new ArrayList<>();
private WifiP2pDeviceListAdapter mAdapter;

在Activity的onCreate()方法中,创建WifiP2pManager和WifiP2pManager.Channel对象:

mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);

4. 注册广播接收器

在Activity中创建以下BroadcastReceiver对象:

mReceiver = new WifiDirectBroadcastReceiver(mManager, mChannel, this);

WifiDirectBroadcastReceiver是一个自定义广播接收器类,它负责处理与Wifi P2P相关的广播事件。

在Activity的onResume()方法中,注册广播接收器:

registerReceiver(mReceiver, mIntentFilter);

在Activity的onPause()方法中,注销广播接收器:

unregisterReceiver(mReceiver);

5. 开始搜索可用设备

通过调用startDiscovery()方法开始搜索可用设备:

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

    @Override
    public void onSuccess() {
        //搜索成功
    }

    @Override
    public void onFailure(int reasonCode) {
        //搜索失败
    }

});

6. 显示可用设备列表

创建一个自定义适配器类WifiP2pDeviceListAdapter,用于显示可用设备列表中的每个设备:

public class WifiP2pDeviceListAdapter extends ArrayAdapter<WifiP2pDevice> {

    private List<WifiP2pDevice> items;
    private Context ctx;

    public WifiP2pDeviceListAdapter(Context context, int textViewResourceId,
                                     List<WifiP2pDevice> objects) {
        super(context, textViewResourceId, objects);

        items = objects;
        ctx = context;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater) ctx.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;
    }

    private String getDeviceStatus(int deviceStatus) {
        switch (deviceStatus) {
            case WifiP2pDevice.AVAILABLE:
                return "可用";
            case WifiP2pDevice.INVITED:
                return "已邀请";
            case WifiP2pDevice.CONNECTED:
                return "已连接";
            case WifiP2pDevice.FAILED:
                return "失败";
            case WifiP2pDevice.UNAVAILABLE:
                return "不可用";
            default:
                return "未知状态";
        }
    }
}

在Activity中,设置ListView的适配器:

mAdapter = new WifiP2pDeviceListAdapter(this, R.layout.row_devices, peers);
ListView listView = (ListView) findViewById(R.id.list_devices);
listView.setAdapter(mAdapter);

在BroadcaseReceiver接收到搜索结果后,在Activity中更新设备列表:

@Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
    peers.clear();
    peers.addAll(peerList.getDeviceList());
    mAdapter.notifyDataSetChanged();
    if (peers.size() == 0) {
        //没有可用设备
    }
}

7. 连接到另一个设备

在设备列表中选择一个设备,并调用connect()方法:

mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {
    @Override
    public void onSuccess() {
        //连接成功
    }
    @Override
    public void onFailure(int reason) {
        //连接失败
    }
});

8. 传输文件

在连接成功后,使用WifiP2pGroup.getClientList()方法获取已连接设备的列表,将文件传输到列表中的第一个设备:

WifiP2pGroup group = (WifiP2pGroup) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
if (group != null) {
    Collection<WifiP2pClient> clients = group.getClientList();
    if (clients.size() > 0) {
        WifiP2pClient client = (WifiP2pClient) clients.toArray()[0];
        File file = new File(filePath);
        if (file.exists()) {
            try {
                FileInputStream inputStream = new FileInputStream(file);
                OutputStream outputStream = client.getOutputStream();
                byte[] buffer = new byte[1024];
                int length;
                while ((length = inputStream.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, length);
                }
                outputStream.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            //文件不存在
        }
    } else {
        //没有连接设备
    }
} else {
    //组不存在
}