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