版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】AndroidStudio如何下载视频到本地
一、先上效果图/upload/information/20200623/125/124043.png/upload/information/20200623/125/124044.png二、使用GreenDao我们需要导入依赖compile
'org.greenrobot:greendao:3.2.2'//依赖
在最后一行插入
apply
plugin:
'org.greenrobot.greendao'
//greenDao在第二行插入
greendao
{//在依赖导入汇总添加一个自动添加数据库表名的配置依赖
schemaVersion
1
//数据库版本号
daoPackage
'com.example.greendaodemo.database'
//设置时生成代码的目录
targetGenDir
'src/main/java'
//设置DaoMaster、DaoSession、Dao目录
}classpath
'org.greenrobot:greendao-gradle-plugin:3.2.2'<uses-permission
android:name="android.permission.INTERNET"/>
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission
android:name="viders.gsf.permission.READ_GSERVICES"
/>三、当然还要有实体类写入实体类后,build下makeproject一下,让他自动生成GreenDao的三个类import
org.greenrobot.greendao.annotation.Entity;
import
org.greenrobot.greendao.annotation.Id;
import
org.greenrobot.greendao.annotation.Generated;
/**
*
author:Created
by
ZhangPengFei.
*
Email:
1271396448@
*
data:
2018/1/18
*/
@Entity
public
class
User
{
@Id
private
Long
id;
private
Integer
thread_id;
private
Integer
start_pos;
private
Integer
end_pos;
private
Integer
compelete_size;
private
String
url;
@Generated(hash
=
2041931179)
public
User(Long
id,
Integer
thread_id,
Integer
start_pos,
Integer
end_pos,
Integer
compelete_size,
String
url)
{
this.id
=
id;
this.thread_id
=
thread_id;
this.start_pos
=
start_pos;
this.end_pos
=
end_pos;
pelete_size
=
compelete_size;
this.url
=
url;
}
@Generated(hash
=
586692638)
public
User()
{
}
public
Long
getId()
{
return
this.id;
}
public
void
setId(Long
id)
{
this.id
=
id;
}
public
Integer
getThread_id()
{
return
this.thread_id;
}
public
void
setThread_id(Integer
thread_id)
{
this.thread_id
=
thread_id;
}
public
Integer
getStart_pos()
{
return
this.start_pos;
}
public
void
setStart_pos(Integer
start_pos)
{
this.start_pos
=
start_pos;
}
public
Integer
getEnd_pos()
{
return
this.end_pos;
}
public
void
setEnd_pos(Integer
end_pos)
{
this.end_pos
=
end_pos;
}
public
Integer
getCompelete_size()
{
return
pelete_size;
}
public
void
setCompelete_size(Integer
compelete_size)
{
pelete_size
=
compelete_size;
}
public
String
getUrl()
{
return
this.url;
}
public
void
setUrl(String
url)
{
this.url
=
url;
}
}四、本人使用了单例模式,所以在全局配置里初始化了数据库的操作import
android.app.Application;
import
com.example.greendaodemo.database.DaoMaster;
import
com.example.greendaodemo.database.DaoSession;
import
com.example.greendaodemo.database.UserDao;
/**
*
author:Created
by
ZhangPengFei.
*
Email:
1271396448@
*
data:
2018/1/18
*/
public
class
App
extends
Application
{
public
static
UserDao
userDao;
@Override
public
void
onCreate()
{
super.onCreate();
DaoMaster.DevOpenHelper
devOpenHelper
=
new
DaoMaster.DevOpenHelper(this,
"zpf.db",
null);
DaoMaster
daoMaster
=
new
DaoMaster(devOpenHelper.getWritableDb());
DaoSession
daoSession
=
daoMaster.newSession();
userDao
=
daoSession.getUserDao();
}
}五、因为我们是多线程,所以写一个保存每个线程下载信息的类public
class
DownLoadInfo
{
/**
*
保存每个下载线程下载信息类
*
*/
private
int
threadId;//
下载器id
private
int
startPos;//
开始点
private
int
endPos;//
结束点
private
int
compeleteSize;//
完成度
private
String
url;//
下载文件的URL地址
public
DownLoadInfo(int
threadId,
int
startPos,
int
endPos,
int
compeleteSize,
String
url)
{
this.threadId
=
threadId;
this.startPos
=
startPos;
this.endPos
=
endPos;
peleteSize
=
compeleteSize;
this.url
=
url;
}
public
DownLoadInfo()
{
}
public
String
getUrl()
{
return
url;
}
public
void
setUrl(String
url)
{
this.url
=
url;
}
public
int
getThreadId()
{
return
threadId;
}
public
void
setThreadId(int
threadId)
{
this.threadId
=
threadId;
}
public
int
getStartPos()
{
return
startPos;
}
public
void
setStartPos(int
startPos)
{
this.startPos
=
startPos;
}
public
int
getEndPos()
{
return
endPos;
}
public
void
setEndPos(int
endPos)
{
this.endPos
=
endPos;
}
public
int
getCompeleteSize()
{
return
compeleteSize;
}
public
void
setCompeleteSize(int
compeleteSize)
{
peleteSize
=
compeleteSize;
}
@Override
public
String
toString()
{
return
"DownloadInfo
[threadId="
+
threadId
+
",
startPos="
+
startPos
+
",
endPos="
+
endPos
+
",
compeleteSize="
+
compeleteSize
+
"]";
}
}六、写一个用来记录的类,修改,添加和下载完清空数据库的操作import
android.util.Log;
import
com.example.greendaodemo.database.UserDao;
import
java.util.ArrayList;
import
java.util.List;
import
static
com.bwie.mtd.App.userDao;
/**
*
author:Created
by
ZhangPengFei.
*
Email:
1271396448@
*
data:
2018/1/18
*/
public
class
DownLoadSqlTool
{
/**
*
创建下载的具体信息
*/
public
void
insertInfos(List<DownLoadInfo>
infos)
{
for
(DownLoadInfo
info
:
infos)
{
User
user
=
new
User(null,
info.getThreadId(),
info.getStartPos(),
info.getEndPos(),
info.getCompeleteSize(),
info.getUrl());
userDao.insert(user);
}
}
/**
*
得到下载具体信息
*/
public
List<DownLoadInfo>
getInfos(String
urlstr)
{
List<DownLoadInfo>
list
=
new
ArrayList<DownLoadInfo>();
List<User>
list1
=
userDao.queryBuilder().where(UserDao.Properties.Url.eq(urlstr)).build().list();
for
(User
user
:
list1)
{
DownLoadInfo
infoss
=
new
DownLoadInfo(
user.getThread_id(),
user.getStart_pos(),
user.getEnd_pos(),
user.getCompelete_size(),
user.getUrl());
Log.d("main",
infoss.toString());
list.add(infoss);
}
return
list;
}
/**
*
更新数据库中的下载信息
*/
public
void
updataInfos(int
threadId,
int
compeleteSize,
String
urlstr)
{
User
user
=
userDao.queryBuilder()
.where(UserDao.Properties.Thread_id.eq(threadId),
UserDao.Properties.Url.eq(urlstr)).build().unique();
user.setCompelete_size(compeleteSize);
userDao.update(user);
}
/**
*
下载完成后删除数据库中的数据
*/
public
void
delete(String
url)
{
userDao.deleteAll();
}
}七、多线程下载的实践类import
android.content.Context;
import
android.os.Handler;
import
android.os.Message;
import
android.util.Log;
import
java.io.File;
import
java.io.InputStream;
import
java.io.RandomAccessFile;
import
.HttpURLConnection;
import
.URL;
import
java.util.ArrayList;
import
java.util.List;
/**
*
author:Created
by
ZhangPengFei.
*
Email:
1271396448@
*
data:
2018/1/18
*/
public
class
DownloadHttpTool
{
/**
*
利用Http协议进行多线程下载具体实践类
*/
private
static
final
String
TAG
=
DownloadHttpTool.class.getSimpleName();
private
int
threadCount;//线程数量
private
String
urlstr;//URL地址
private
Context
mContext;
private
Handler
mHandler;
private
List<DownLoadInfo>
downloadInfos;//保存下载信息的类
private
String
localPath;//目录
private
String
fileName;//文件名
private
int
fileSize;
private
DownLoadSqlTool
sqlTool;//文件信息保存的数据库操作类
private
enum
Download_State
{
Downloading,
Pause,
Ready;//利用枚举表示下载的三种状态
}
private
Download_State
state
=
Download_State.Ready;//当前下载状态
private
int
globalCompelete
=
0;//所有线程下载的总数
public
DownloadHttpTool(int
threadCount,
String
urlString,
String
localPath,
String
fileName,
Context
context,
Handler
handler)
{
super();
this.threadCount
=
threadCount;
this.urlstr
=
urlString;
this.localPath
=
localPath;
this.mContext
=
context;
this.mHandler
=
handler;
this.fileName
=
fileName;
sqlTool
=
new
DownLoadSqlTool();
}
//在开始下载之前需要调用ready方法进行配置
public
void
ready()
{
Log.w(TAG,
"ready");
globalCompelete
=
0;
downloadInfos
=
sqlTool.getInfos(urlstr);
if
(downloadInfos.size()
==
0)
{
initFirst();
}
else
{
File
file
=
new
File(localPath
+
"/"
+
fileName);
if
(!file.exists())
{
sqlTool.delete(urlstr);
initFirst();
}
else
{
fileSize
=
downloadInfos.get(downloadInfos.size()
-
1)
.getEndPos();
for
(DownLoadInfo
info
:
downloadInfos)
{
globalCompelete
+=
info.getCompeleteSize();
}
Log.w(TAG,
"globalCompelete:::"
+
globalCompelete);
}
}
}
public
void
start()
{
Log.w(TAG,
"start");
if
(downloadInfos
!=
null)
{
if
(state
==
Download_State.Downloading)
{
return;
}
state
=
Download_State.Downloading;
for
(DownLoadInfo
info
:
downloadInfos)
{
Log.v(TAG,
"startThread");
new
DownloadThread(info.getThreadId(),
info.getStartPos(),
info.getEndPos(),
info.getCompeleteSize(),
info.getUrl()).start();
}
}
}
public
void
pause()
{
state
=
Download_State.Pause;
}
public
void
delete()
{
compelete();
File
file
=
new
File(localPath
+
"/"
+
fileName);
file.delete();
}
public
void
compelete()
{
sqlTool.delete(urlstr);
}
public
int
getFileSize()
{
return
fileSize;
}
public
int
getCompeleteSize()
{
return
globalCompelete;
}
//第一次下载初始化
private
void
initFirst()
{
Log.w(TAG,
"initFirst");
try
{
URL
url
=
new
URL(urlstr);
HttpURLConnection
connection
=
(HttpURLConnection)
url
.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
fileSize
=
connection.getContentLength();
Log.w(TAG,
"fileSize::"
+
fileSize);
File
fileParent
=
new
File(localPath);
if
(!fileParent.exists())
{
fileParent.mkdir();
}
File
file
=
new
File(fileParent,
fileName);
if
(!file.exists())
{
file.createNewFile();
}
//
本地访问文件
RandomAccessFile
accessFile
=
new
RandomAccessFile(file,
"rwd");
accessFile.setLength(fileSize);
accessFile.close();
connection.disconnect();
}
catch
(Exception
e)
{
e.printStackTrace();
}
int
range
=
fileSize
/
threadCount;
downloadInfos
=
new
ArrayList<DownLoadInfo>();
for
(int
i
=
0;
i
<
threadCount
-
1;
i++)
{
DownLoadInfo
info
=
new
DownLoadInfo(i,
i
*
range,
(i
+
1)
*
range
-
1,
0,
urlstr);
downloadInfos.add(info);
}
DownLoadInfo
info
=
new
DownLoadInfo(threadCount
-
1,
(threadCount
-
1)
*
range,
fileSize
-
1,
0,
urlstr);
downloadInfos.add(info);
sqlTool.insertInfos(downloadInfos);
}
//自定义下载线程
private
class
DownloadThread
extends
Thread
{
private
int
threadId;
private
int
startPos;
private
int
endPos;
private
int
compeleteSize;
private
String
urlstr;
private
int
totalThreadSize;
public
DownloadThread(int
threadId,
int
startPos,
int
endPos,
int
compeleteSize,
String
urlstr)
{
this.threadId
=
threadId;
this.startPos
=
startPos;
this.endPos
=
endPos;
totalThreadSize
=
endPos
-
startPos
+
1;
this.urlstr
=
urlstr;
peleteSize
=
compeleteSize;
}
@Override
public
void
run()
{
HttpURLConnection
connection
=
null;
RandomAccessFile
randomAccessFile
=
null;
InputStream
is
=
null;
try
{
randomAccessFile
=
new
RandomAccessFile(localPath
+
"/"
+
fileName,
"rwd");
randomAccessFile.seek(startPos
+
compeleteSize);
URL
url
=
new
URL(urlstr);
connection
=
(HttpURLConnection)
url.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
connection.setRequestProperty("Range",
"bytes="
+
(startPos
+
compeleteSize)
+
"-"
+
endPos);
is
=
connection.getInputStream();
byte[]
buffer
=
new
byte[1024];
int
length
=
-1;
while
((length
=
is.read(buffer))
!=
-1)
{
randomAccessFile.write(buffer,
0,
length);
compeleteSize
+=
length;
Message
message
=
Message.obtain();
message.what
=
threadId;
message.obj
=
urlstr;
message.arg1
=
length;
mHandler.sendMessage(message);
sqlTool.updataInfos(threadId,
compeleteSize,
urlstr);
Log.w(TAG,
"Threadid::"
+
threadId
+
"
compelete::"
+
compeleteSize
+
"
total::"
+
totalThreadSize);
if
(compeleteSize
>=
totalThreadSize)
{
break;
}
if
(state
!=
Download_State.Downloading)
{
break;
}
}
}
catch
(Exception
e)
{
e.printStackTrace();
}
finally
{
try
{
if
(is
!=
null)
{
is.close();
}
randomAccessFile.close();
connection.disconnect();
}
catch
(Exception
e)
{
e.printStackTrace();
}
}
}
}
}八、再写一个接口类import
android.annotation.SuppressLint;
import
android.content.Context;
import
android.os.AsyncTask;
import
android.os.Handler;
import
android.os.Message;
import
android.util.Log;
/**
*
author:Created
by
ZhangPengFei.
*
Email:
1271396448@
*
data:
2018/1/18
*/
public
class
DownloadUtil
{
private
DownloadHttpTool
mDownloadHttpTool;
private
OnDownloadListener
onDownloadListener;
private
int
fileSize;
private
int
downloadedSize
=
0;
@SuppressLint("HandlerLeak")
private
Handler
mHandler
=
new
Handler()
{
@Override
public
void
handleMessage(Message
msg)
{
//
TODO
Auto-generated
method
stub
super.handleMessage(msg);
int
length
=
msg.arg1;
synchronized
(this)
{//加锁保证已下载的正确性
downloadedSize
+=
length;
}
if
(onDownloadListener
!=
null)
{
onDownloadListener.downloadProgress(downloadedSize);
}
if
(downloadedSize
>=
fileSize)
{
mDownloadHttpTpelete();
if
(onDownloadListener
!=
null)
{
onDownloadListener.downloadEnd();
}
}
}
};
public
DownloadUtil(int
threadCount,
String
filePath,
String
filename,
String
urlString,
Context
context)
{
mDownloadHttpTool
=
new
DownloadHttpTool(threadCount,
urlString,
filePath,
filename,
context,
mHandler);
}
//下载之前首先异步线程调用ready方法获得文件大小信息,之后调用开始方法
public
void
start()
{
new
AsyncTask<Void,Void,Void>()
{
@Override
protected
Void
doInBackground(Void...
arg0)
{
//
TODO
Auto-generated
method
stub
mDownloadHttpTool.ready();
return
null;
}
@Override
protected
void
onPostExecute(Void
result)
{
//
TODO
Auto-generated
method
stub
super.onPostExecute(result);
fileSize
=
mDownloadHttpTool.getFileSize();
downloadedSize
=
mDownloadHttpTool.getCompeleteSize();
Log.w("Tag",
"downloadedSize::"
+
downloadedSize);
if
(onDownloadListener
!=
null)
{
onDownloadListener.downloadStart(fileSize);
}
mDownloadHttpTool.start();
}
}.execute();
}
public
void
pause()
{
mDownloadHttpTool.pause();
}
public
void
delete(){
mDownloadHttpTool.delete();
}
public
void
reset(){
mDownloadHttpTool.delete();
start();
}
public
void
setOnDownloadListener(OnDownloadListener
onDownloadListener)
{
this.onDownloadListener
=
onDownloadListener;
}
//下载回调接口
public
interface
OnDownloadListener
{
public
void
downloadStart(int
fileSize);
public
void
downloadProgress(int
downloadedSize);//记录当前所有线程下总和
public
void
downloadEnd();
}
}九、写一下自己的布局文件<?xml
version="1.0"
encoding="utf-8"?>
<RelativeLayout
xmlns:android="/apk/res/android"
xmlns:app="/apk/res-auto"
xmlns:tools="/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.mtd.MainActivity">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="fill_parent"
android:layout_height="7.5dp"
android:layout_centerInParent="true"
android:layout_marginRight="8dp"
android:max="100"
android:progress="100"
android:visibility="visible"
/>
<TextView
android:id="@+id/tv_Progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/progressBar"
android:layout_centerHorizontal="true"
android:layout_marginLeft="23dp"
android:layout_marginStart="23dp"
android:layout_marginTop="18dp"
android:text=""
/>
<Button
android:id="@+id/downLoad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="100dp"
android:text="下载"
/>
<Button
android:id="@+id/pause"
android:layout_toRightOf="@id/downLoad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="48dp"
android:layout_marginStart="48dp"
android:text="暂停"
/>
</RelativeLayout>十、奉上自己的Java代码MainActivity类import
android.os.Bundle;
import
android.os.Environment;
import
android.support.v7.app.AppCompatActivity;
import
android.util.Log;
import
android.view.View;
import
android.widget.Button;
import
android.widget.ProgressBar;
import
android.widge
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年信阳航空职业学院单招职业倾向性测试题库及答案详解1套
- 2026年南京旅游职业学院单招职业倾向性考试题库附答案详解(满分必刷)
- 2026年六盘水职业技术学院单招职业倾向性考试题库及答案详解参考
- 2026年内蒙古能源职业学院单招职业技能考试题库及答案详解(有一套)
- 2026年包头钢铁职业技术学院单招职业技能测试题库含答案详解(模拟题)
- 2026年兰考三农职业学院单招职业适应性考试题库及答案详解(夺冠系列)
- 2026年南充电影工业职业学院单招职业倾向性测试题库附答案详解(综合卷)
- 2026年保定电力职业技术学院单招职业倾向性测试题库附参考答案详解(巩固)
- 2026年兰州航空职业技术学院单招职业倾向性考试题库附参考答案详解(黄金题型)
- 2025-2030甘肃能源行业市场现状供需分析及投资评估规划分析研究报告
- 旅游规划与产品开发
- 2025年税务会计期末试题及答案
- (2025年)麻醉综合疗法在孤独症谱系障碍儿童中临床应用的专家共识
- 2025年广东中考历史试卷真题解读及答案讲评课件
- 全膝关节置换术患者心理因素关联探究:疼痛信念、自我效能与睡眠质量
- 后循环缺血护理常规课件
- T-HAS 148-2025 工厂化菌糠栽培双孢蘑菇技术规程
- 宇树科技在服务机器人市场的竞争策略 课件
- 农村兄弟二人分家协议书范文
- 两办意见八硬措施煤矿安全生产条例宣贯学习课件
- 高考3500词乱序版
评论
0/150
提交评论