您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Android Studio如何下載視頻到本地,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
一、先上效果圖
二、使用GreenDao我們需要導入依賴
1.以下在項目gradle依賴中添加
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目錄 }
2.以下在工程gradle依賴中添加
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
3.既然我們要聯網下載,讀寫權限肯定不能忘記了
<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="com.google.android.providers.gsf.permission.READ_GSERVICES" />
三、當然還要有實體類寫入實體類后,build下make project一下,讓他自動生成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@qq.com * 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; this.compelete_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 this.compelete_size; } public void setCompelete_size(Integer compelete_size) { this.compelete_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@qq.com * 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; this.compeleteSize = 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) { this.compeleteSize = 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@qq.com * 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 java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.List; /** * author:Created by ZhangPengFei. * Email: 1271396448@qq.com * 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; this.compeleteSize = 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@qq.com * 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) { mDownloadHttpTool.compelete(); 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="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/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.widget.TextView; public class MainActivity extends AppCompatActivity { private final String videoUrl = "http://2449.vod.myqcloud.com/2449_22ca37a6ea9011e5acaaf51d105342e3.f20.mp4"; private TextView tv_progress;//進度顯示 private ProgressBar progressBar;//進度條 private Button downLoad;//下載按鈕 private Button pause;//暫停按鈕 private String path;//下載路徑 private int max; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_progress = (TextView) findViewById(R.id.tv_Progress); progressBar = (ProgressBar) findViewById(R.id.progressBar); downLoad = (Button) findViewById(R.id.downLoad); pause = (Button) findViewById(R.id.pause); path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/local"; final DownloadUtil downloadUtil = new DownloadUtil(4, path, "drum.mp4", videoUrl, this); downloadUtil.setOnDownloadListener(new DownloadUtil.OnDownloadListener() { @Override public void downloadStart(int fileSize) { Log.i("TAG---fileSize", fileSize + ""); max = fileSize;//文件總長度 progressBar.setMax(fileSize); } @Override public void downloadProgress(int downloadedSize) { Log.i("TAG---downloadedSize", downloadedSize + ""); progressBar.setProgress(downloadedSize); tv_progress.setText((int) downloadedSize * 100 / max + "%"); } @Override public void downloadEnd() { Log.i("TAG---end", "End"); } }); /** * 下載的點擊事件 */ downLoad.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { downloadUtil.start(); } }); /** * 暫停的點擊事件 */ pause.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { downloadUtil.pause(); } }); } }
關于“Android Studio如何下載視頻到本地”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。