在我的上一篇文章:[Android 实现无网络传输文件](https://juejin.cn/post/6844903565186596872),我介绍了通过 Wifi Direct(Wifi 直连)实现 Android 设备之间进行文件传输的方法,可以在无移动网络的情况下实现点对点的文件传输
本来觉得这样也就够了,可在要应用到实际项目的时候,又考虑到用户的设备系统版本可能并不都符合要求(Wifi Direct 是 Android 4.0 后支持的功能,话说低于 4.4 版本的手机应该都很少了吧?),而且我也不确定 IOS 系统是否支持 Wifi Direct,所以为了让文件传输逻辑可以应用到更多的设备上,就又实现了通过 Wifi热点 进行文件传输的功能
相比于通过 Wiif Direct 进行文件传输,通过 Wifi 热点进行设备配对更加方便,逻辑也更为直接,传输一个1G左右的压缩包用了5分钟左右的时间,平均传输速率有 3.5 M/S 左右。此外,相对于上个版本,新版本除了提供传输进度外,还提供了传输速率、预估完成时间、文件传输前后的MD5码等数据
实现的效果如下所示:
开启Ap热点接收文件
![](https://www.writebug.com/myres/static/uploads/2022/7/21/0fa60356e2f6c39743d14044a151a96b.writebug)
连接Wiif热点发送文件
![](https://www.writebug.com/myres/static/uploads/2022/7/21/737bf8ebaeb2d5f44a8836ea0ee9c5dc.writebug)
文件传输完成后校验文件完整性
![](https://www.writebug.com/myres/static/uploads/2022/7/21/22dafdece451add81b8c48a3ef8f6a9f.writebug)
开发步骤分为以下几点:
1. 在 AndroidManifest 中声明相关权限(网络和文件读写权限)
2. 文件接收端开启Ap热点,作为服务器端建立Socket,在指定端口等待客户端的连接
3. 文件发送端连接到Wifi热点,作为客户端主动连接到服务器端
4. 文件发送端将待发送的文件信息模型(包括文件路径,文件大小和文件MD5码等信息)通过Socket发送给文件接收端
5. 文件发送端发起实际的文件传输请求,接收端和发送端根据已接收到或已发送的的文件字节数,计算文件传输进度、文件传输速率和预估完成时间等数据
6. 文件传输结束后,对比文件信息模型携带来的MD5码值与本地文件重新计算生成的MD5码是否相等,以此校验文件完整性
### 一、声明权限
本应用并不会消耗移动数据,但由于要使用到 Wifi 以及 Java Socket,所以需要申请网络相关的权限。此外,由于是要实现文件互传,所以也需要申请SD卡读写权限。
```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.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" />
```
### 二、文件接收端
文件接收端作为服务器存在,需要主动开启Ap热点供文件发送端连接,由于通过反射来开启热点的方法在高版本系统上无法实现,所以需要用户主动去开启热点,并设置固定的热点名称
此处需要先定义一个文件信息模型 FileTransfer ,FileTransfer 包含三个字段,MD5码值用于校验文件的完整性,fileLength 是为了用于计算文件的传输进度和传输速率
```java
public class FileTransfer implements Serializable {
//文件路径
private String filePath;
//文件大小
private long fileLength;
//MD5码
private String md5;
···
}
```
Ap热点开启成功后,就可以启动一个服务在后台等待文件发送端来主动连接了,这里使用 IntentService 在后台监听客户端的Socket连接请求,并通过输入输出流来传输文件。此处的代码比较简单,就只是在指定端口一直堵塞监听客户端的连接请求,获取待传输的文件信息模型 FileTransfer ,之后就进行实际的数据传输
文件传输速率是每一秒计算一次,根据这段时间内接收的字节数与消耗的时间做除法,从而得到传输速率,再通过将剩余的未传输字节数与传输速率做除法,从而得到预估的剩余传输时间
```java
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null && ACTION_START_RECEIVE.equals(intent.getAction())) {
clean();
File file = null;
Exception exception = null;
try {
serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(Constants.PORT));
Socket client = serverSocket.accept();
Log.e(TAG, "客户端IP地址 : " + client.getInetAddress().getHostAddress());
inputStream = client.getInputStream();
objectInputStream = new ObjectInputStream(inputStream);
fileTransfer = (FileTransfer) objectInputStream.readObject();
Log.e(TAG, "待接收的文件: " + fileTransfer);
if (fileTransfer == null) {
exception = new Exception("从文件发送端发来的文件模型为null");
return;
} else if (TextUtils.isEmpty(fileTransfer.getMd5())) {
exception = new Exception("从文件发送端发来的文件模型不包含MD5码");
return;
}
String name = new File(fileTransfer.getFilePath()).getName();
//将文件存储至指定位置
file = new File(Environment.getExternalStorageDirectory() + "/" + name);
fileOutputStream = new FileOutputStream(file);
startCallback();
byte[] buf = new byte[512];
int len;
while ((len = inputStream.read(buf)) != -1) {
fileOutputStream.write(buf, 0, len);
total += len;
}
Log.e(TAG, "文件接收成功");
stopCallback();
if (progressChangListener != null) {
//因为上面在计算文件传输进度时因为小数点问题可能不会显示到100%,所以此处手动将之设为100%
progressChangListener.onProgressChanged(fileTransfer, 0, 100, 0, 0, 0, 0);
//开始计算传输到本地的文件的MD5码
progressChangListener.onStartComputeMD5();
}
} catch (Exception e) {
Log.e(TAG, "文件接收 Exception: " + e.getMessage());
exception = e;
} finally {
FileTransfer transfer = new FileTransfer();
if (file != null && file.exists()) {
transfer.setFilePath(file.getPath());
transfer.setFileSize(file.length());
transfer.setMd5(Md5Util.getMd5(file));
Log.e(TAG, "计算出的文件的MD5码是:" + transfer.getMd5());
}
if (exception != null) {
if (progressChangListener != null) {
progressChangListener.onTransferFailed(transfer, exception);
}
} else {
if (progressChangListener != null && fileTransfer != null) {
if (fileTransfer.getMd5().equals(transfer.getMd5())) {
progressChangListener.onTransferSucceed(transfer);
} else {
//如果本地计算出的MD5码和文件发送端传来的�
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
资源包含文件:设计报告word+项目源码 相比于通过 Wiif Direct 进行文件传输,通过 Wifi 热点进行设备配对更加方便,详细介绍参考:https://biyezuopin.blog.csdn.net/article/details/125927674
资源推荐
资源详情
资源评论
收起资源包目录
实现Android手机之间在局域网下传输任意文件.zip (49个子文件)
设计报告.docx 294KB
gradlew.bat 2KB
gradlew 5KB
gradle.properties 783B
LICENSE 1KB
app
proguard-rules.pro 751B
src
test
java
github
leavesc
wififiletransfer
ExampleUnitTest.java 420B
androidTest
java
github
leavesc
wififiletransfer
ExampleInstrumentedTest.java 744B
main
res
mipmap-xxxhdpi
ic_launcher.png 9KB
ic_launcher_round.png 15KB
drawable
ic_launcher_background.xml 5KB
mipmap-hdpi
ic_launcher.png 3KB
ic_launcher_round.png 5KB
drawable-v24
ic_launcher_foreground.xml 2KB
values
colors.xml 208B
strings.xml 79B
styles.xml 560B
mipmap-xxhdpi
ic_launcher.png 6KB
ic_launcher_round.png 10KB
mipmap-mdpi
ic_launcher.png 2KB
ic_launcher_round.png 3KB
mipmap-xhdpi
ic_launcher.png 4KB
ic_launcher_round.png 7KB
mipmap-anydpi-v26
ic_launcher_round.xml 270B
ic_launcher.xml 270B
layout
activity_file_receiver.xml 1002B
activity_main.xml 1KB
activity_file_sender.xml 761B
java
github
leavesc
wififiletransfer
manager
ApManager.java 8KB
WifiLManager.java 8KB
model
FileTransfer.java 1KB
MainActivity.java 2KB
common
Logger.java 396B
Constants.java 437B
Md5Util.java 2KB
BaseActivity.java 1KB
FileReceiverActivity.java 7KB
service
FileSenderService.java 13KB
FileReceiverService.java 12KB
FileSenderActivity.java 7KB
AndroidManifest.xml 2KB
.gitignore 7B
build.gradle 951B
gradle
wrapper
gradle-wrapper.jar 53KB
gradle-wrapper.properties 232B
.gitignore 131B
README.md 22KB
settings.gradle 15B
build.gradle 576B
共 49 条
- 1
shejizuopin
- 粉丝: 9537
- 资源: 1288
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
- 4
前往页