Android 实现断点上传文件
使用Socket TCP/IP方式进行文件上传
代码:
package com.example.androidseekuploadfile; import java.io.File; import java.io.OutputStream; import java.io.PushbackInputStream; import java.io.RandomAccessFile; import java.net.Socket; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.example.androidseekuploadfile.db.UploadLogService; import com.example.androidseekuploadfile.tools.StreamTool; /** * android实现断点上传文件 * @author miaowei * */ public class MainActivity extends Activity { /** * 文件名 */ private EditText filenameEditText; /** * 上传结果 */ private TextView resultView; /** * 等待框 */ private ProgressBar uploadBar; /** * 上传服务 */ private UploadLogService logService; /** * 是否开启上传 */ private boolean start = true; /** * 上传 */ private Button btn_upload; /** * 暂停 */ private Button btn_stop; /** * 本地测试 */ String pathString = Environment.getExternalStorageDirectory().getAbsolutePath(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); logService = new UploadLogService(this); filenameEditText = (EditText)this.findViewById(R.id.filename); uploadBar = (ProgressBar) this.findViewById(R.id.uploadbar); resultView = (TextView)this.findViewById(R.id.result); btn_upload =(Button)this.findViewById(R.id.btn_upload); btn_stop =(Button)this.findViewById(R.id.btn_stop); btn_upload.setOnClickListener(onClickListener); btn_stop.setOnClickListener(onClickListener); } /** * 事件处理 */ private OnClickListener onClickListener = new OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_upload://上传 start = true; String filename = filenameEditText.getText().toString(); //判断SDCard是否存在 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ //取得SDCard的目录 //File uploadFile = new File(Environment.getExternalStorageDirectory(), filename); //本地测试使用 File uploadFile = new File(pathString+"/Android/data/com.mapbar.info.collection/files/cache.zip"); if(uploadFile.exists()){ //开始上传文件 uploadFile(uploadFile); }else{ Toast.makeText(MainActivity.this,"文件不存在",Toast.LENGTH_SHORT).show(); } }else{ Toast.makeText(MainActivity.this,"未检测到SD卡", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_stop://暂停 start = false; break; default: break; } } }; /** * 上传文件 * 启动一个线程,使用Handler来避免UI线程ANR错误 * @param uploadFile */ private void uploadFile(final File uploadFile) { new Thread(new Runnable() { @Override public void run() { try { //设置长传文件的最大刻度 uploadBar.setMax((int)uploadFile.length()); //判断文件是否已有上传记录 String souceid = logService.getBindId(uploadFile); //构造拼接协议 String head = "Content-Length="+ uploadFile.length() + ";filename="+ uploadFile.getName() + ";sourceid="+ (souceid==null? "" : souceid)+"\r\n"; //通过Socket取得输出流 //测试使用,具体自配 Socket socket = new Socket("192.168.1.10",8080); OutputStream outStream = socket.getOutputStream(); outStream.write(head.getBytes()); PushbackInputStream inStream = new PushbackInputStream(socket.getInputStream()); //获取到字符流的id与位置 String response = StreamTool.readLine(inStream); String[] items = response.split(";"); String responseid = items[0].substring(items[0].indexOf("=")+1); String position = items[1].substring(items[1].indexOf("=")+1); //代表原来没有上传过此文件,往数据库添加一条绑定记录 if(souceid==null){ logService.save(responseid, uploadFile); } RandomAccessFile fileOutStream = new RandomAccessFile(uploadFile, "r"); fileOutStream.seek(Integer.valueOf(position)); byte[] buffer = new byte[1024]; int len = -1; //初始化长传的数据长度 int length = Integer.valueOf(position); while(start&&(len = fileOutStream.read(buffer)) != -1){ outStream.write(buffer, 0, len); //设置长传数据长度 length += len; Message msg = new Message(); msg.getData().putInt("size", length); mHandler.sendMessage(msg); } fileOutStream.close(); outStream.close(); inStream.close(); socket.close(); //判断上传完则删除数据 if(length==uploadFile.length()){ logService.delete(uploadFile); } } catch (Exception e) { e.printStackTrace(); } } }).start(); } /** * 使用Handler给创建他的线程发送消息 * UI更新 */ private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { //获得上传长度的进度 int length = msg.getData().getInt("size"); uploadBar.setProgress(length); float num = (float)uploadBar.getProgress()/(float)uploadBar.getMax(); //设置显示结果 int result = (int)(num * 100); resultView.setText(result+ "%"); //上传成功 if(uploadBar.getProgress()==uploadBar.getMax()){ Toast.makeText(MainActivity.this, "上传成功", Toast.LENGTH_SHORT).show(); } } }; }
package com.example.androidseekuploadfile.db; import java.io.File; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; /** * 操作数据库 * @author miaowei * */ public class UploadLogService { private DBOpenHelper dbOpenHelper; public UploadLogService(Context context){ this.dbOpenHelper = new DBOpenHelper(context); } /** * 保存上传文件断点数据 * @param sourceid 标识ID * @param uploadFile 文件 */ public void save(String sourceid, File uploadFile){ SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); db.execSQL("insert into uploadlog(uploadfilepath, sourceid) values(?,?)", new Object[]{uploadFile.getAbsolutePath(),sourceid}); } /** * 文件上传完成,删除上传文件断点数据 * @param uploadFile */ public void delete(File uploadFile){ SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); db.execSQL("delete from uploadlog where uploadfilepath=?", new Object[]{uploadFile.getAbsolutePath()}); } /** * 根据文件的上传路径得到绑定的id * @param uploadFile * @return */ public String getBindId(File uploadFile){ SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("select sourceid from uploadlog where uploadfilepath=?", new String[]{uploadFile.getAbsolutePath()}); if(cursor.moveToFirst()){ return cursor.getString(0); } return null; } }
package com.example.androidseekuploadfile.db; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; /** * 数据库帮助类 * @author miaowei * */ public class DBOpenHelper extends SQLiteOpenHelper { /** * 文件名 */ private String uploadfilepath; /** * 记录文件标识 */ private String sourceid; public DBOpenHelper(Context context) { super(context, "upload.db", null, 1); } /** * 创建数据库 */ @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE uploadlog (_id integer primary key autoincrement, uploadfilepath varchar(100), sourceid varchar(10))"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS uploadlog"); onCreate(db); } }
分享:http://blog.csdn.net/shimiso/article/details/8529633
具体操作见附件源码:
相关推荐
本篇文章将详细介绍如何在Android中实现大文件的断点上传,并围绕提供的`okhttpUpLoader-master`文件进行解析。 首先,我们要理解`OkHttp`库在Android中的重要性。`OkHttp`是一个高效的HTTP客户端,它通过连接池、...
在Android开发中,断点上传是一项重要的功能,它允许用户在中断网络连接后从上次停止的位置继续上传大文件,提高了用户体验。本实例将探讨如何在Android应用中实现断点上传,以及与服务器端的交互机制。 一、...
在Android上实现文件断点上传,主要涉及以下几个关键技术点: 1. 文件分块:为了实现断点续传,文件通常被分割成多个小块进行上传。这样即使某个块传输失败,也只需重新上传该块,而不是整个文件。 2. 服务器端...
在Android开发中,断点上传是一项重要的功能,它允许用户在网络连接不稳定或者设备突然断电的情况下,能够继续之前未完成的文件上传过程。这通常涉及到网络编程,特别是使用Socket通信机制来实现。以下是对这个主题...
Android 多线程可断点续传上传文件至服务器Demo(Android端编辑器:Android Studio,服务器端编辑器:Eclipse,请注意手机默认下载目录必须要有t007.zip,服务器端必须有D:\temp\temp目录)
总之,这个“android开发教程 文件断点上传”将带你走进Android文件上传的世界,通过实际操作,你将学会如何创建一个功能完备、健壮的文件断点上传器。通过视频学习和源码分析,你的编程技能和解决问题的能力都将...
总结,实现Android中的自定义协议文件断点上传涉及协议设计、Socket连接、文件分割、块上传以及错误处理等多个环节。这个过程需要对网络编程有深入理解,同时考虑到网络状况和用户体验,确保上传的可靠性和效率。...
Android应用源码之Android中Socket大文件断点上传_Android
总结,实现Android应用中的断点续传功能主要涉及以下几个关键点:检查本地已下载部分,获取文件总大小,创建输入/输出流,更新下载进度,以及异常处理。使用HttpURLConnection可以方便地实现这些操作,提高应用的...
首先,我们需要理解的是Android文件上传的基本流程。通常,小文件的上传可以通过HttpURLConnection或者OkHttp等HTTP库来完成,但这些方法并不适合大文件,因为它们无法很好地处理网络中断的情况。因此,我们通常会...
在安卓(Android)平台上,开发过程中常常需要处理大文件的传输问题,比如用户...在压缩包中的`AndroidSocket`文件可能包含了详细的源码示例,开发者可以通过学习和理解这些代码,更好地掌握大文件断点上传的实现方法。
在Android平台上,大文件的上传是一项挑战,因为考虑到网络稳定性、设备性能以及用户体验等因素。在标题"android大文件分段上传"中提到的方法,是通过使用Socket流将大文件分段进行上传,这是一种有效应对大文件传输...
本篇文章将详细探讨如何使用Socket实现Android客户端的文件断点续传功能,主要针对POST请求场景。 首先,我们需要理解什么是断点续传。断点续传是一种在网络传输中断后,可以从上次断开的位置继续传输的技术,避免...
在Android开发中,断点下载和断点上传是提高用户下载和上传大文件体验的关键技术。断点下载允许用户在中断后从上次停止的位置继续下载,而断点上传则允许用户在上传过程中暂停并稍后恢复,这尤其适用于网络不稳定或...
在Android开发中,当...总结起来,Android中使用Socket实现大文件断点上传涉及文件分块、Socket通信、断点记录、异常处理等多个环节。通过这种方式,可以提高大文件上传的效率和用户体验,尤其在网络不稳定的情况下。
综上所述,Android多文件断点续传涉及到了文件操作、网络请求、并发控制、进度保存和用户界面等多个方面的技术。通过这个Demo,开发者可以学习到如何将这些技术整合到一个实际的应用中,提升应用的性能和用户体验。
在这个“Android TCPIP断点上传文件Demo”中,开发者将学习如何实现在Android设备上通过TCP/IP协议进行断点续传的文件上传功能,同时服务器端是用Eclipse开发的,这表明涉及到Java后端的知识。 首先,让我们理解TCP...
Android 文件断点续传源码可以下在直接用的
本篇文章将详细讲解如何在Android应用中实现FTP文件上传,支持断点续传以及在网络中断后能继续之前的传输。 首先,我们需要在项目中引入FTP客户端库。Apache Commons Net是一个常用的FTP客户端库,可以通过Gradle...