android wifi直连 wifip2pmanager

2024-04-16 05:28

本文主要是介绍android wifi直连 wifip2pmanager,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

android wifi直连 wifip2pmanager;使用WiFi 直连,然后通过udp进行通讯。
Android WiFi 直连(Wi-Fi Direct,也称为Wi-Fi P2P)是一种让两台或多台设备通过Wi-Fi技术直接进行点对点连接的技术,无需借助传统的无线路由器或接入点。这种技术使得设备间可以快速建立安全的无线连接,实现文件传输、屏幕共享、游戏对战等多种应用,尤其适用于智能手机、平板电脑、打印机、相机等消费电子设备间的近距离通信。

以下是Android WiFi 直连的基本工作原理和使用步骤:

工作原理:
设备发现:启用Wi-Fi Direct功能的设备可以通过广播信号搜索和发现附近的其他支持Wi-Fi Direct的设备。设备间可以互相检测到对方的存在,并显示在设备列表中供用户选择。

连接请求:用户在设备列表中选择要连接的目标设备后,发起连接请求。目标设备收到请求后,通常需要手动或自动确认接受连接。

组建立:一旦连接请求被接受,两台设备之间会自动建立一个Wi-Fi Direct组。在这个组中,一台设备会被选为“组主人”(Group Owner,GO),相当于小型网络的接入点,负责管理组内的连接和数据传输。另一台设备则作为“客户端”(Client)加入该组。

数据传输:连接建立后,组主人和客户端设备可以使用各自的IP地址和端口号进行直接的TCP/UDP通信。应用程序可以利用这些网络参数创建Socket连接,进行文件传输、消息传递等操作。

例子代码:

public class WifiConnectActivity extends AppCompatActivity {private Button btnConnect;private WifiDirectLink wifiDirectLink;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);LinearLayout linearLayout = new LinearLayout(this);linearLayout.setOrientation(LinearLayout.VERTICAL);setContentView(linearLayout);btnConnect = new AppCompatButton(this);btnConnect.setText("链接");AppCompatButton btnConnect2 = new AppCompatButton(this);btnConnect2.setText("发送");linearLayout.addView(btnConnect);linearLayout.addView(btnConnect2);wifiDirectLink = new WifiDirectLink(getApplicationContext());// 按钮点击事件 - 连接到对等设备btnConnect.setOnClickListener(v -> wifiDirectLink.connectToPeer());btnConnect2.setOnClickListener(v -> wifiDirectLink.send("hello".getBytes()));if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.NEARBY_WIFI_DEVICES}, 119);} else {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 119);}}@Overrideprotected void onDestroy() {wifiDirectLink.release();super.onDestroy();}}

连接工具类:

import android.annotation.SuppressLint;
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.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;import androidx.core.content.ContextCompat;import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;public class WifiDirectLink {private static final String TAG = "WifiDirectLink";private final WifiP2pManager wifiP2pManager;private final WifiP2pManager.Channel channel;private Context context;private final Handler handler = new Handler(Looper.getMainLooper());private SyncUDP udp;private String otherClientIp;public WifiDirectLink(Context context) {this.context = context;Log.i(TAG, "WifiDirectLink: begin start-----------------------------------------------");if (udp == null) {udp = new SyncUDP(Config.BROADCAST_PORT + 3);udp.setListener(this::receiveAction);}// 初始化Wi-Fi P2P管理器和通道wifiP2pManager = (WifiP2pManager) context.getSystemService(Context.WIFI_P2P_SERVICE);channel = wifiP2pManager.initialize(context, Looper.getMainLooper(), null);// 创建意图过滤器并添加所需的意图动作IntentFilter intentFilter = new IntentFilter();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);// 注册广播接收器ContextCompat.registerReceiver(context, broadcastReceiver, intentFilter, ContextCompat.RECEIVER_EXPORTED);handler.postDelayed(new Runnable() {@Overridepublic void run() {try {discoverPeers();} catch (Exception e) {e.printStackTrace();}handler.postDelayed(this, 8888);}}, 88);}private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {Log.i(TAG, "onReceive: " + intent.getAction());String action = intent.getAction();if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {// 获取连接信息WifiP2pInfo wifiP2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);if (wifiP2pInfo != null) {new Thread(() -> {// 获取groupOwnerAddressInetAddress groupOwnerAddress = wifiP2pInfo.groupOwnerAddress;// 在这里可以使用groupOwnerAddress进行相应的操作if (groupOwnerAddress != null) {String hostAddress = groupOwnerAddress.getHostAddress();String hostName = groupOwnerAddress.getHostName();byte[] address = groupOwnerAddress.getAddress();String canonicalHostName = groupOwnerAddress.getCanonicalHostName();Log.i(TAG, "onReceive: get host address:" + hostAddress + "; " + hostName + "; " + address + "; " + canonicalHostName);// start socket connectotherClientIp = hostAddress;if (!TextUtils.isEmpty(otherClientIp)) {new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context.getApplicationContext(), "获取鬣主任ip", Toast.LENGTH_LONG).show());}}}).start();}}}};public void send(byte[] buf) {// 广播 都接受得到Log.i(TAG, "send: other client ip:" + otherClientIp);if (udp == null || otherClientIp == null) return;new Thread(() -> {String substring = otherClientIp.substring(0, otherClientIp.lastIndexOf("."));substring = substring + ".255";udp.sendAction(buf, substring);}).start();}@SuppressLint("MissingPermission")public void discoverPeers() throws Exception {wifiP2pManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {@Overridepublic void onSuccess() {Log.i(TAG, "onSuccess: scan wifi node");}@Overridepublic void onFailure(int i) {Log.i(TAG, "onFailure: No nodes scanned");}});}@SuppressLint("MissingPermission")public void connectToPeer() {Log.i(TAG, "connectToPeer: start connect");wifiP2pManager.requestPeers(channel, wifiP2pDeviceList -> {List<WifiP2pDevice> deviceList = new ArrayList<>(wifiP2pDeviceList.getDeviceList());Log.i(TAG, "connectToPeer: item count:" + deviceList.size());if (deviceList.size() == 0) {return;}for (WifiP2pDevice item : deviceList) {Log.i(TAG, "connectToPeer: item name:" + item.deviceName + "; " + item.deviceAddress);// 创建连接配置WifiP2pConfig config = new WifiP2pConfig();config.deviceAddress = item.deviceAddress;connectItem(config, item);}});}@SuppressLint("MissingPermission")private void connectItem(WifiP2pConfig config, WifiP2pDevice item) {try {wifiP2pManager.connect(channel, config, new WifiP2pManager.ActionListener() {@Overridepublic void onSuccess() {Log.i(TAG, "onSuccess: Link successful for:" + item.deviceName + "; " + item.deviceAddress);}@Overridepublic void onFailure(int reasonCode) {Log.i(TAG, "onFailure: Link failure for:" + item.deviceName + "; " + item.deviceAddress);}});} catch (Exception e) {e.printStackTrace();Log.i(TAG, "getDevices: connect item error:" + e.getMessage());}}private void receiveAction(byte[] buffer, int len, String ip) {Log.i(TAG, "receiveAction: ip:" + ip + "; len:" + len);}public void release() {handler.removeCallbacksAndMessages(null);if (udp != null) {udp.release();udp = null;}try {context.unregisterReceiver(broadcastReceiver);} catch (Exception e) {e.printStackTrace();Log.i(TAG, "release: error:" + e.getMessage());}try {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) channel.close();} catch (Exception e) {e.printStackTrace();Log.i(TAG, "release:close channel error:" + e.getMessage());}}
}

udp 通讯类:

import android.util.Log;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class SyncUDP implements Runnable {private static final String TAG = "ReceiveUDP";private Thread thread;private DatagramSocket socket;private OnUpdateListener listener;private int port;public void setListener(OnUpdateListener listener) {this.listener = listener;}public void release() {if (thread != null && !thread.isInterrupted())thread.interrupt();listener = null;closeSocket();if (thread != null) {try {thread.join();} catch (Exception e) {e.printStackTrace();}thread = null;}}public SyncUDP(int port) {this.port = port;thread = new Thread(this);thread.start();}public void sendAction(byte[] buf, String ip) {if (socket == null || socket.isClosed()) return;try {DatagramPacket sendPacket = new DatagramPacket(buf, buf.length);sendPacket.setAddress(InetAddress.getByName(ip));sendPacket.setPort(port);socket.send(sendPacket);} catch (Exception e) {e.printStackTrace();Log.i(TAG, "sendAction: send package error:" + e.getMessage());}}@Overridepublic void run() {while (!Thread.interrupted()) {try {byte[] by = new byte[16];socket = new DatagramSocket(port);socket.setBroadcast(true);while (!Thread.interrupted()) {try {// receive dataDatagramPacket receivePacket = new DatagramPacket(by, by.length);Log.i(TAG, "run: start wait package");// Join threadsocket.receive(receivePacket);String ip = receivePacket.getAddress().getHostAddress();Log.i(TAG, "run: get package len:" + receivePacket.getLength() + "; ip:" + ip);if (listener != null)listener.onUpdateUI(receivePacket.getData(), receivePacket.getLength(), ip);} catch (Exception e) {e.printStackTrace();break;}}closeSocket();} catch (Exception e) {e.printStackTrace();}}closeSocket();}private void closeSocket() {if (socket != null) {if (!socket.isClosed()) {try {socket.close();} catch (Exception e) {e.printStackTrace();}}socket = null;}}public interface OnUpdateListener {void onUpdateUI(byte[] buffer, int len, String ip);}
}

这篇关于android wifi直连 wifip2pmanager的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907891

相关文章

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR

Android逆向(反调,脱壳,过ssl证书脚本)

文章目录 总结 基础Android基础工具 定位关键代码页面activity定位数据包参数定位堆栈追踪 编写反调脱壳好用的脚本过ssl证书校验抓包反调的脚本打印堆栈bilibili反调的脚本 总结 暑假做了两个月的Android逆向,记录一下自己学到的东西。对于app渗透有了一些思路。 这两个月主要做的是代码分析,对于分析完后的持久化等没有学习。主要是如何反编译源码,如何找到

企业安全之WiFi篇

很多的公司都没有安全团队,只有运维来负责整个公司的安全,从而安全问题也大打折扣。我最近一直在给各个公司做安全检测,就把自己的心得写下来,有什么不足之处还望补充。 0×01  无线安全 很多的公司都有不怎么注重公司的无线电安全,有钱的公司买设备,没钱的公司搞人力。但是人的技术在好,没有设备的辅助,人力在牛逼也没有个卵用。一个好的路由器、交换机、IDS就像你装备了 无尽、狂徒、杀人书一