国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android Studio 下載視頻到本地

2019-10-22 18:14:29
字體:
供稿:網(wǎng)友

最近在研究視頻下載到本地的問題,像愛奇藝,騰訊視頻,迅雷看看等等一些視頻播放器,如果在一個播放器里面視頻下載到一半用戶退出App之后,再次登錄從頭開始,那么就太可悲了,所以在做視頻音頻類的項目時,要實現(xiàn)的一個功能就是斷點續(xù)傳,就是將用戶下載的視頻或者音頻等以字節(jié)流的形式存入數(shù)據(jù)庫,下次用戶再次下載時,將繼續(xù)上次數(shù)據(jù)庫的接著下載,這樣用戶體驗就會很好,也大大節(jié)省了成本.

好了廢話不多說,開始今天的正題.

一、先上效果圖

android,studio,下載視頻到本地,視頻下載到電腦android,studio,下載視頻到本地,視頻下載到電腦

二、使用GreenDao我們需要導(dǎo)入依賴

1.以下在項目gradle依賴中添加

compile 'org.greenrobot:greendao:3.2.2'//依賴 在最后一行插入apply plugin: 'org.greenrobot.greendao' //greenDao在第二行插入greendao {//在依賴導(dǎo)入?yún)R總添加一個自動添加數(shù)據(jù)庫表名的配置依賴 schemaVersion 1 //數(shù)據(jù)庫版本號 daoPackage 'com.example.greendaodemo.database' //設(shè)置時生成代碼的目錄 targetGenDir 'src/main/java' //設(shè)置DaoMaster、DaoSession、Dao目錄}

2.以下在工程gradle依賴中添加

classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'

3.既然我們要聯(lián)網(wǎng)下載,讀寫權(quán)限肯定不能忘記了

<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" /> 

三、當(dāng)然還要有實體類寫入實體類后,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;  } } 

四、本人使用了單例模式,所以在全局配置里初始化了數(shù)據(jù)庫的操作

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;// 結(jié)束點  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     + "]";  } } 

六、寫一個用來記錄的類,修改,添加和下載完清空數(shù)據(jù)庫的操作

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 {  /**   * 創(chuàng)建下載的具體信息   */  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;  }  /**   * 更新數(shù)據(jù)庫中的下載信息   */  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);  }  /**   * 下載完成后刪除數(shù)據(jù)庫中的數(shù)據(jù)   */  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協(xié)議進(jìn)行多線程下載具體實踐類   */  private static final String TAG = DownloadHttpTool.class.getSimpleName();  private int threadCount;//線程數(shù)量  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;//文件信息保存的數(shù)據(jù)庫操作類  private enum Download_State {   Downloading, Pause, Ready;//利用枚舉表示下載的三種狀態(tài)  }  private Download_State state = Download_State.Ready;//當(dāng)前下載狀態(tài)  private int globalCompelete = 0;//所有線程下載的總數(shù)  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();  }  //在開始下載之前需要調(diào)用ready方法進(jìn)行配置  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);  }  //下載之前首先異步線程調(diào)用ready方法獲得文件大小信息,之后調(diào)用開始方法  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;  }  //下載回調(diào)接口  public interface OnDownloadListener {   public void downloadStart(int fileSize);   public void downloadProgress(int downloadedSize);//記錄當(dāng)前所有線程下總和   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"   style="?android:attr/progressBarStyleHorizontal"   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;//進(jìn)度顯示  private ProgressBar progressBar;//進(jìn)度條  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();    }   });  } } 

 


注:相關(guān)教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 大竹县| 堆龙德庆县| 绵竹市| 南涧| 封丘县| 健康| 建德市| 芦溪县| 宜兰县| 徐闻县| 舞钢市| 宁陕县| 福安市| 宽城| 西安市| 禄劝| 新营市| 巴彦淖尔市| 永昌县| 安国市| 沐川县| 都匀市| 乃东县| 和政县| 邢台市| 固安县| 安多县| 长寿区| 卫辉市| 张家港市| 林州市| 台中县| 庆云县| 宣城市| 大港区| 芦溪县| 长春市| 理塘县| 兴安县| 务川| 安康市|