Android 如何实现无网络传输文件

本文介绍了如何在Android系统中利用Wifi P2P技术实现在没有网络的情况下,进行手机间的文件传输。详细阐述了从声明权限、注册广播、服务器端创建群组、客户端加入群组及文件传输请求到校验文件完整性的完整过程。
摘要由CSDN通过智能技术生成

最近的项目需要实现一个 Android 手机之间无网络传输文件的功能,就发现了 Wifi P2P(Wifi点对点)这么一个功能,最后也实现了通过 Wifi 隔空传输文件的功能,这里我也来整理下代码,分享给大家。


Wifi P2P 是在 Android 4.0 以及更高版本系统中加入的功能,通过 Wifi P2P 可以在不连接网络的情况下,直接与配对的设备进行数据交换。相对于蓝牙,Wifi P2P 的搜索速度和传输速度更快,传输距离更远

实现的效果如下所示:



一般而言,开发步骤分为以下几点:

  • 在 AndroidManifest 中声明相关权限(网络和文件读写权限)

  • 获取 WifiP2pManager ,注册相关广播监听Wifi直连的状态变化

  • 指定某一台设备为服务器(用来接收文件),创建群组并作为群主存在,在指定端口监听客户端的连接请求,等待客户端发起连接请求以及文件传输请求

  • 客户端(用来发送文件)主动搜索附近的设备,加入到服务器创建的群组,获取服务器的IP地址,向其发起文件传输请求

  • 校验文件完整性

一、声明权限

Wifi P2P 技术并不会访问网络,但由于会使用到 Java socket,所以需要申请网络权限。此外,由于是要实现文件互传,所以也需要申请SD卡读写权限。

    <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.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
二、注册广播

与 Wifi P2P 相关的广播有以下几个:

  • WIFI_P2P_STATE_CHANGED_ACTION( 用于指示 Wifi P2P 是否可用 )

  • WIFI_P2P_PEERS_CHANGED_ACTION( 对等节点列表发生了变化 )

  • WIFI_P2P_CONNECTION_CHANGED_ACTION( Wifi P2P 的连接状态发生了改变 )

  • WIFI_P2P_THIS_DEVICE_CHANGED_ACTION( 本设备的设备信息发生了变化 )

当接收到这几个广播时,我们都需要到 WifiP2pManager (对等网络管理器)来进行相应的信息请求,此外还需要用到 Channel 对象作为请求参数

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

当收到WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION 广播时,可以判断当前 Wifi P2P是否可用

int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
    mDirectActionListener.wifiP2pEnabled(true);
} else {
    mDirectActionListener.wifiP2pEnabled(false);                
}

当收到WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION 广播时,意味设备周围的可用设备列表发生了变化,可以通过 requestPeers 方法得到可用的设备列表,之后就可以选择当中的某一个设备进行连接操作

mWifiP2pManager.requestPeers(mChannel, new WifiP2pManager.PeerListListener() {    @Override
    public void onPeersAvailable(WifiP2pDeviceList peers) {
        mDirectActionListener.onPeersAvailable(peers.getDeviceList());
    }
});

当收到WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION 广播时,意味着 Wifi P2P 的连接状态发生了变化,可能是连接到了某设备,或者是与某设备断开了连接

NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);if (networkInfo.isConnected()) {
    mWifiP2pManager.requestConnectionInfo(mChannel, new WifiP2pManager.ConnectionInfoListener() {        @Override
        public void onConnectionInfoAvailable(WifiP2pInfo info) {
            mDirectActionListener.onConnectionInfoAvailable(info);
        }
    });
    Log.e(TAG, "已连接p2p设备");
} else {
    mDirectActionListener.onDisconnection();
    Log.e(TAG, "与p2p设备已断开连接");
}

如果是与某设备连接上了,则可以通过requestConnectionInfo 方法获取到连接信息

当收到WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION 广播时,则可以获取到本设备变化后的设备信息

(WifiP2pDevice) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)

可以看出 Wifi P2P 的接口高度异步化,到现在已经用到了三个系统的回调函数,一个用于 WifiP2pManager 的初始化,两个用于在广播中异步请求数据,为了简化操作,此处统一使用一个自定义的回调函数,方法含义与系统的回调函数一致

public interface DirectActionListener extends WifiP2pManager.ChannelListener {
  
   void wifiP2pEnabled(boolean enabled);    
   void onConnectionInfoAvailable(WifiP2pInfo wifiP2pInfo);    
   void onDisconnection();    
   void
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值