大文件断点续传

大文件断点续传
1.服务包
1.1 DBOpenHelper.java
package cn.itcast.service;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBOpenHelper extends SQLiteOpenHelper {

	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);		
	}

}
2.UploadLogService.java
package cn.itcast.service;

import java.io.File;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class UploadLogService {
	private DBOpenHelper dbOpenHelper;
	
	public UploadLogService(Context context){
		this.dbOpenHelper = new DBOpenHelper(context);
	}
	
	public void save(String sourceid, File uploadFile){
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		db.execSQL("insert into uploadlog(uploadfilepath, sourceid) values(?,?)",
				new Object[]{uploadFile.getAbsolutePath(),sourceid});
	}
	
	public void delete(File uploadFile){
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		db.execSQL("delete from uploadlog where uploadfilepath=?", new Object[]{uploadFile.getAbsolutePath()});
	}
	
	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;
	}
}
2.工具包
 StreamTool.java

package cn.itcast.utils;

import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream;

public class StreamTool {     public static void save(File file, byte[] data) throws Exception {    FileOutputStream outStream = new FileOutputStream(file);    outStream.write(data);    outStream.close();   }     public static String readLine(PushbackInputStream in) throws IOException {    char buf[] = new char[128];    int room = buf.length;    int offset = 0;    int c; loop:  while (true) {     switch (c = in.read()) {      case -1:      case '\n':       break loop;      case '\r':       int c2 = in.read();       if ((c2 != '\n') && (c2 != -1)) in.unread(c2);       break loop;      default:       if (--room < 0) {        char[] lineBuffer = buf;        buf = new char[offset + 128];           room = buf.length - offset - 1;           System.arraycopy(lineBuffer, 0, buf, 0, offset);                }       buf[offset++] = (char) c;       break;     }    }    if ((c == -1) && (offset == 0)) return null;    return String.copyValueOf(buf, 0, offset);  }    /**  * 读取流  * @param inStream  * @return 字节数组  * @throws Exception  */  public static byte[] readStream(InputStream inStream) throws Exception{    ByteArrayOutputStream outSteam = new ByteArrayOutputStream();    byte[] buffer = new byte[1024];    int len = -1;    while( (len=inStream.read(buffer)) != -1){     outSteam.write(buffer, 0, len);    }    outSteam.close();    inStream.close();    return outSteam.toByteArray();  } }

3.上传文件程序代码
3.1 monitor.java
package cn.king.monitor;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.Button;

public class Monitor extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_monitor);
		
		Button filemanager = (Button) findViewById(R.id.fileManager);		
		filemanager.setOnClickListener(new Button.OnClickListener(){
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			Intent intent = new Intent();
			intent.setClass(Monitor.this, FileManager.class);
			/* 调用一个新的Activity */ 
			startActivity(intent);
			}
		 });
		
	}

	/*@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.monitor, menu);
		return true;
	}*/

}
3.2  FileManager.java
package cn.king.monitor;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class FileManager extends Activity {

	ListView listView;
	TextView textView;
	// 记录当前的父文件夹
	File currentParent;
	// 记录当前路径下的所有文件的文件数组
	File[] currentFiles;
	public int MID;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.array_file);

		listView = (ListView) findViewById(R.id.list);
		textView = (TextView) findViewById(R.id.path);
		// 获取系统的SD卡的目录
		File root = new File("/mnt/sdcard/");
		// 如果 SD卡存在
		if (root.exists()) {
			currentParent = root;
			currentFiles = root.listFiles();
			// 使用当前目录下的全部文件、文件夹来填充ListView
			inflateListView(currentFiles);
		}

		// 为ListView的列表项的单击事件绑定监听器
		listView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				// 用户单击了文件,直接返回,不做任何处理
				if (currentFiles[position].isFile())
					return;
				// 获取用户点击的文件夹下的所有文件
				File[] tmp = currentFiles[position].listFiles();
				if (tmp == null || tmp.length == 0) {
					Toast.makeText(FileManager.this, "当前路径不可访问或该路径下没有文件",
							Toast.LENGTH_SHORT).show();
				} else {
					// 获取用户单击的列表项对应的文件夹,设为当前的父文件夹
					currentParent = currentFiles[position]; // ②
					// 保存当前的父文件夹内的全部文件和文件夹
					currentFiles = tmp;
					// 再次更新ListView
					inflateListView(currentFiles);
				}
			}
		});
		ItemOnLongClick1();
	}
	// 为ListView的列表项的長按事件绑定监听器
	private void ItemOnLongClick1() {
		// 注:setOnCreateContextMenuListener是与下面onContextItemSelected配套使用的
		listView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {

			@Override
			public void onCreateContextMenu(ContextMenu menu, View v,
					ContextMenuInfo menuInfo) {
				// TODO Auto-generated method stub
				menu.add(0, 0, 0, "播放");
				menu.add(0, 1, 0, "删除");
				menu.add(0, 2, 0, "上传");
			}
		});
	}

	// 长按菜单响应函数
	public boolean onContextItemSelected(MenuItem item) {

		AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
				.getMenuInfo();
		MID = (int) info.id;// 这里的info.id对应的就是数据库中_id的值

		switch (item.getItemId()) {
		case 0:
			// 添加操作
			Toast.makeText(FileManager.this, "添加", Toast.LENGTH_SHORT).show();
			break;

		case 1:
			// 删除操作
			break;

		case 2:// 上传
			
			int position = 0;
			//创建一个Bundle
			//String title = currentFiles[BIND_AUTO_CREATE].getName().toString();
			String title = currentFiles[position].getName().toString();
			Bundle bundle = new Bundle();
			bundle.putString("title", title);
			//创建一个Intent
			Intent intent = new Intent();
			intent.setClass(FileManager.this, UploadActivity.class);
			intent.putExtras(bundle);
			//调用一个新的Activity 
			startActivity(intent);
		default:
			break;
		}

		return super.onContextItemSelected(item);

	}

	private void inflateListView(File[] files) // ①
	{
		// 创建一个List集合,List集合的元素是Map
		List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
		for (int i = 0; i < files.length; i++) {
			Map<String, Object> listItem = new HashMap<String, Object>();
			// 如果当前File是文件夹,使用folder图标;否则使用file图标
			if (files[i].isDirectory()) {
				listItem.put("icon", R.drawable.folder);
			} else {
				listItem.put("icon", R.drawable.file);
			}
			listItem.put("fileName", files[i].getName());
			// 添加List项
			listItems.add(listItem);
			
		}
		// 创建一个SimpleAdapter
		SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems,
				R.layout.array_line, new String[] { "icon", "fileName" },
				new int[] { R.id.icon, R.id.file_name });
		// 为ListView设置Adapter
		listView.setAdapter(simpleAdapter);
		try {
			textView.setText("当前路径为:" + currentParent.getCanonicalPath());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
} 
 3.3  UploadActivity.java   
package cn.king.monitor;

import java.io.File;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.io.RandomAccessFile;
import java.net.Socket;

import cn.itcast.service.UploadLogService;
import cn.itcast.utils.StreamTool;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class UploadActivity extends Activity {
   
    private TextView filenameText , resulView;
    private ProgressBar uploadbar;
    private UploadLogService logService;
    private Handler handler = 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);
			resulView.setText(result+ "%");
			if(uploadbar.getProgress()==uploadbar.getMax()){
				Toast.makeText(UploadActivity.this, R.string.success, 1).show();
			}
		}
    };
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.array_upload);
        
        Intent intent = getIntent();
        String title = (String)intent.getStringExtra("title");
        
        logService = new UploadLogService(this);
        filenameText = (TextView)this.findViewById(R.id.filename);
        uploadbar = (ProgressBar) this.findViewById(R.id.uploadbar);
        resulView = (TextView)this.findViewById(R.id.result);
        
        filenameText.setText(title);
        
        Button button =(Button)this.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				String filename = filenameText.getText().toString();
				if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
					File uploadFile = new File(Environment.getExternalStorageDirectory(), filename);
					if(uploadFile.exists()){
						uploadFile(uploadFile);
					}else{
						Toast.makeText(UploadActivity.this, R.string.filenotexsit, Toast.LENGTH_LONG).show();
					}
				}else{
					Toast.makeText(UploadActivity.this, R.string.sdcarderror, Toast.LENGTH_LONG).show();
				}
			}
		});
    }
    /**
     * 上传文件
     * @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 = new Socket("172.18.168.195", 8989);
					OutputStream outStream = socket.getOutputStream();
					outStream.write(head.getBytes());
					
					PushbackInputStream inStream = new PushbackInputStream(socket.getInputStream());	
					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( (len = fileOutStream.read(buffer)) != -1){
						outStream.write(buffer, 0, len);
						length += len;
						Message msg = new Message();
						msg.getData().putInt("size", length);
						handler.sendMessage(msg);
					}
					fileOutStream.close();
					outStream.close();
		            inStream.close();
		            socket.close();
		            if(length==uploadFile.length()) logService.delete(uploadFile);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
	}
}


你可能感兴趣的:(大文件断点续传)