Android 文件實現斷點上傳

n7w77 9年前發布 | 4K 次閱讀 Java 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() + ";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();    
            } 
        }

    };

}

?

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

 本文由用戶 n7w77 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!