Android 文件实现断点上传

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

使用Socket TCP/IP方式进行文件上传

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
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() + ";source" : 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();   
            }
        }
         
    };
 
}

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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
    }
     
}

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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