基于Android的文件传输零碎

开发步骤
  • 在 AndroidManifest 中申明相干权限(网络和文件读写权限)
  • 获取 WifiP2pManager ,注册相干播送监听Wifi直连的状态变动
  • 指定某一台设施为服务器(用来接管文件),创立群组并作为群主存在,在指定端口监听客户端的连贯申请,期待客户端发动连贯申请以及文件传输申请

客户端(用来发送文件)被动搜寻左近的设施,退出到服务器创立的群组,获取服务器的 IP 地址,向其发动文件传输申请

  • 校验文件完整性
设置Android权限

Wifi P2P 技术并不会拜访网络,但因为会应用到 Java Socket,所以须要申请网络权限。此外,因为是要实现文件互传,所以也须要申请SD卡读写权限。

    <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" />    <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_FINE_LOCATION" />
注册播送
与 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 onSelfDeviceAvailable(WifiP2pDevice wifiP2pDevice);    void onPeersAvailable(Collection<WifiP2pDevice> wifiP2pDeviceList);}//所以,整个播送接收器应用到的所有代码是:public class DirectBroadcastReceiver extends BroadcastReceiver {    private static final String TAG = "DirectBroadcastReceiver";    private WifiP2pManager mWifiP2pManager;    private WifiP2pManager.Channel mChannel;    private DirectActionListener mDirectActionListener;    public DirectBroadcastReceiver(WifiP2pManager wifiP2pManager, WifiP2pManager.Channel channel, DirectActionListener directActionListener) {        mWifiP2pManager = wifiP2pManager;        mChannel = channel;        mDirectActionListener = directActionListener;    }    public static IntentFilter getIntentFilter() {        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);        return intentFilter;    }    @Override    public void onReceive(Context context, Intent intent) {        Log.e(TAG, "接管到播送: " + intent.getAction());        if (!TextUtils.isEmpty(intent.getAction())) {            switch (intent.getAction()) {                // 用于批示 Wifi P2P 是否可用                case WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION: {                    int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);                    if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {                        mDirectActionListener.wifiP2pEnabled(true);                    } else {                        mDirectActionListener.wifiP2pEnabled(false);                        List<WifiP2pDevice> wifiP2pDeviceList = new ArrayList<>();                        mDirectActionListener.onPeersAvailable(wifiP2pDeviceList);                    }                    break;                }                // 对等节点列表产生了变动                case WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION: {                    mWifiP2pManager.requestPeers(mChannel, new WifiP2pManager.PeerListListener() {                        @Override                        public void onPeersAvailable(WifiP2pDeviceList peers) {                            mDirectActionListener.onPeersAvailable(peers.getDeviceList());                        }                    });                    break;                }                // Wifi P2P 的连贯状态产生了扭转                case WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION: {                    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设施已断开连接");                    }                    break;                }                //本设施的设施信息产生了变动                case WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION: {                    mDirectActionListener.onSelfDeviceAvailable((WifiP2pDevice) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));                    break;                }            }        }    }}

未完待续.....................................

成果展现

[图片上传失败...(image-89ef4a-1604286797706)]
[图片上传失败...(image-d1227e-1604286797706)]


最初