文件下载
文件下载:
实现文件下载管理,实现单线程断点续传,界面显示多个下载记录,
但只能点击单独一个可以继续下载,如果点击多个出现相应提示,在下载
列表里将所有Sdcard下的PDF文件全部显示出来,点击调用PDF浏览器,
如果没有浏览器提示无法显示。
完成已经下载完成的文件查看,删除:
MVC
V层Adapter实现
C层Activity实现
V和C层实现 订购/通知
M层使用单例,工厂,模板
C层中将需求提出:
1, 查询目录下的文件返回List
2, 删除指定文件(参数文件名)
3, 查看指定文件(参数文件名,context上下文)
由DownloadedInterface接口声明以上的3个方法,
由于1,2需求是不会改变的,但是在3中如果文件是PDF,DOC,TXT那么在打开的时候具体的逻辑是不同的。
那么就可以用模板方式将前2个需求实现,将第三个需求定义成抽象,子类继承模板类单独实现抽象的3需求,好处是如果需求更改,需要加入其他文件类型的时候只需要继承模板类实现需求3就可以了,因为需求1,2是不变的。
如果需求更改,需要在Activity中添加多个DownloadedInterface的获取指定文件的类,或者添加多个判断:
判断是pdf,判断是doc,判断是txt。
这样C层中的代码复用可能性也不大,有没有什么好的方式去解耦呢?
可以使用工厂模式,
DownloadedObjectFactory类(单例),私有构造中声明List里面加上map,key是文件类型(其实就相当于文件夹的路径),value是Obj的(需要将符合Key的类装入到list中进行缓存,这样的好处是在初始化的时候耗时,但是以后就不需要再创建,并且是全局的随时可以使用)。在构造中添加所有的文件类比如doc,txt,pdf等等,DownloadedObjectFactory定义成单例,在下面有getDownloadObjForName方法(参数是文件名/文件夹名)返回DownloadedInterface这样在使用的时候只需要将文件名或文件夹名传入,返回的自然就是你需要的类了,如果需要扩展只需要,继承模板类实现需求3,并在list中加入key和value,在使用的时候直接
DownloadedInterface downloadedInterface =DownloadedObjectFactory.getInstance().getDownloadObjForName(文件名/文件夹名);就可以了
其实简单看好像没有什么必要实现工厂,但是这样可以实现解耦,并且C层是不需要知道用户需要的格式是什么格式,这样也保证了复用性。
以上是M层。
下面是C和V层之间的订购/通知实现,
interface DownloadedDelegat声明方法DownloadedDelegate(文件名,点击类型)
在V层定义DownloadedDelegat,并实现set方法,在长按(暂定删除)调用DownloadedDelegate(文件名,长按类型),在点击查看时调用方法传入文件名和点击类型。
在c层Activity中实现DownloadedDelegat接口中的方法,adapter调用set代理,就可以实现订购/通知,而在实现的接口方法中可以判断点击的类型,并调用相应的删除/查看方法通知到M层去实现,C层必须知道V层传入的事件类型,但是没有必要知道具体操作的是什么文件,所以只要调用删除和查看,但是具体删除什么文件,查看什么文件C层是不需要知道的,这是需要M层做的事情。
不需要担心文件的类型出错只要传入的没有错,调用的就没有错,当创建的时候就是传入文件的类型,所以返回的接口肯定也是这个类型的。并且使用了单例和缓存中的list不会出现问题。
整个工程结构:

把源码传上来以备以后查阅(按包名类名):
package com.hsm.Activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity
{
private Button b1;
private Button b2;
private Button b3;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.setContentView(R.layout.first);
b1 = (Button)findViewById(R.id.button1);
b2 = (Button)findViewById(R.id.button2);
b3 = (Button)findViewById(R.id.button3);
intent = new Intent();
b1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
intent.setClass(MainActivity.this,ResumeBrokenDownloadsActivity.class);
intent.putExtra("url", "http://192.168.10.113:8080/a.pdf");
startActivity(intent);
}
});
b2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
intent.setClass(MainActivity.this,ResumeBrokenDownloadsActivity.class);
intent.putExtra("url", "http://192.168.10.113:8080/b.pdf");
startActivity(intent);
}
});
b3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
intent.setClass(MainActivity.this,ResumeBrokenDownloadsActivity.class);
intent.putExtra("url", "http://192.168.10.113:8080/c.pdf");
startActivity(intent);
}
});
}
}
上面的是进入的首界面activity
下面是进入后显示已经下载完成的list的activity
package com.hsm.Activity;
import java.util.List;
import com.hsm.downloadedfile.DownloadedPDF;
import com.hsm.factory.DownloadedObjectFactory;
import com.hsm.modelinterface.DownloadedDelegat;
import com.hsm.modelinterface.DownloadedInterface;
import com.hsm.view.DownloadedAdapter;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ListView;
public class ResumeBrokenDownloadsActivity extends Activity implements DownloadedDelegat{
/** Called when the activity is first created. */
private List<String> list ;
private ListView downloadedListView;
private DownloadedAdapter downloadedAdapter;
private DownloadedInterface downloadedInterface;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//显示已经下载完成的文件
downloadedInterface = DownloadedObjectFactory.getInstance().getDownloadObjForName("pdf");
list = downloadedInterface.queryDownloadedFiles();
downloadedAdapter = new DownloadedAdapter(this, list);
downloadedAdapter.setDelegate(this);
downloadedListView = (ListView)findViewById(R.id.downloaded_list);
downloadedListView.setAdapter(downloadedAdapter);
//显示正在下载的文件
Intent intent = getIntent();
String nameString = intent.getStringExtra("url");
//TODO 如果nameString是空就表示从其他入口进来不是从下载入口进来
}
@Override
public void DownloadedDelegate(String name, int event)
{
if (event==1)//删除
{
downloadedInterface.removeFileForName(name);
Message msg = new Message();
msg.obj = "flush";
flushHandler.sendMessage(msg);
}else if(event==2){//查看
downloadedInterface.openDownloadedFile(name,this);
}
}
//刷新已下载完成的Adapter
private Handler flushHandler = new Handler() {
public void handleMessage(Message msg)
{
if ("flush".equals(msg.obj))
{
downloadedAdapter.notifyDataSetChanged();
}
}
};
}
下面是具体实现查询下载完成Fild逻辑的类:
package com.hsm.downloadedfile;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.widget.Toast;
import com.hsm.modelinterface.DownloadedInterface;
public abstract class DownloadedFild implements DownloadedInterface
{
protected List<String> pdfList;
protected File sdDir;
protected String sdPath = Environment.getExternalStorageDirectory().toString();// 获取跟目录
public DownloadedFild(String folderPath) {
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED))
{
pdfList = new ArrayList<String>();
sdDir = new File(sdPath+"/"+folderPath);
File[] allFile = sdDir.listFiles();
for (int i = 0; i < allFile.length; i++)
{
pdfList.add(allFile[i].getName());
}
}else {
//TODO 否则表示无sdcard
}
}
@Override
public List<String> queryDownloadedFiles()
{
return pdfList;
}
@Override
public void removeFileForName(String fileName)
{
pdfList.remove(fileName);
File file = new File(sdDir+"/"+fileName);
if (!file.exists())
{
return;
}
// 如果file的路径是文件夹
// if (!file.isDirectory())
// {
// return;
// }
file.delete();
}
@Override
public abstract void openDownloadedFile(String fileName , Context context);
}
下面的是实现删除具体文件的类继承了上面的查询类DownloadedFild只实现了public abstract void openDownloadedFile(String fileName , Context context);
package com.hsm.downloadedfile;
import java.io.File;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.Toast;
public class DownloadedPDF extends DownloadedFild
{
public DownloadedPDF(String folderPath)
{
super(folderPath);
}
@Override
public void openDownloadedFile(String fileName, Context context)
{
Intent intent = new Intent("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri localUri = Uri.fromFile(new File(sdDir+"/"+fileName));
intent.setDataAndType(localUri, "application/pdf");
try
{
context.startActivity(intent);
}
catch (Exception e)
{
// TODO Auto-generated catch block
Toast.makeText(context, "无可用程序打开此文件!", 0).show();
}
}
}

浙公网安备 33010602011771号