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

首頁 > 系統 > Android > 正文

Android讀取本地照片和視頻相冊實例代碼

2019-10-22 23:17:06
字體:
來源:轉載
供稿:網友

前言

項目中經常要選擇本地照片或者視頻的需求,如果去掃描整個SD卡就太耗時間,其實Android系統在啟動時就已經把整個設備中的多媒體文件信息(文件名,類型,大小等)都存到了數據庫,然后提供了ContentPrivider這個API來管理這個數據庫,我們可以利用ContentPrivider來獲取所有的照片和視頻。

ContentPrivider初識

先看下管理的的數據庫在哪

data/data/目錄下:有很多這種文件夾(日歷,聯系人,下載管理,多媒體等)

android,讀取相冊照片,讀取本地相冊,Android讀取本地照片

我們需要的照片和視頻就在media下面,進去看看。進去找到database然后打開external.db,就可以看到多張表(音頻,文件,Log,圖像,視頻等)

android,讀取相冊照片,讀取本地相冊,Android讀取本地照片

照片相冊

那么獲取照片直接通過 ContentProvider讀取Images這個數據庫就OK了,這里開啟工作線程讀取所有.jpeg和.png的圖片,附上代碼段:

 /**  * 讀取手機中所有圖片信息  */ private void getAllPhotoInfo() {  new Thread(new Runnable() {   @Override   public void run() {    List<MediaBean> mediaBeen = new ArrayList<>();    HashMap<String,List<MediaBean>> allPhotosTemp = new HashMap<>();//所有照片    Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;    String[] projImage = { MediaStore.Images.Media._ID      , MediaStore.Images.Media.DATA      ,MediaStore.Images.Media.SIZE      ,MediaStore.Images.Media.DISPLAY_NAME};    Cursor mCursor = getContentResolver().query(mImageUri,      projImage,      MediaStore.Images.Media.MIME_TYPE + "=? or " + MediaStore.Images.Media.MIME_TYPE + "=?",      new String[]{"image/jpeg", "image/png"},      MediaStore.Images.Media.DATE_MODIFIED+" desc");    if(mCursor!=null){     while (mCursor.moveToNext()) {      // 獲取圖片的路徑      String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA));      int size = mCursor.getInt(mCursor.getColumnIndex(MediaStore.Images.Media.SIZE))/1024;      String displayName = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));      //用于展示相冊初始化界面      mediaBeen.add(new MediaBean(MediaBean.Type.Image,path,size,displayName));      // 獲取該圖片的父路徑名      String dirPath = new File(path).getParentFile().getAbsolutePath();      //存儲對應關系      if (allPhotosTemp.containsKey(dirPath)) {       List<MediaBean> data = allPhotosTemp.get(dirPath);       data.add(new MediaBean(MediaBean.Type.Image,path,size,displayName));       continue;      } else {       List<MediaBean> data = new ArrayList<>();       data.add(new MediaBean(MediaBean.Type.Image,path,size,displayName));       allPhotosTemp.put(dirPath,data);      }     }     mCursor.close();    }    //更新界面    runOnUiThread(new Runnable() {     @Override     public void run() {      //...     }    });   }  }).start(); }

有四點需要注意:

  1. MediaBean是文件實體類,代碼就不貼了
  2. 照片集合不是放在List<MediaBean>這樣存儲的,而是HashMap<String,List<MediaBean>>,這樣把圖片已文件夾(也就是父目錄)分類,更節省內存,其次支持相冊展示不同文件夾的照片
  3. 貌似沒辦法獲取當前設備的拍照默認路徑,有的設備是/DCIM,有的是/100andro還有/camera,那相冊就默認展示最近所有照片吧。然后給用戶列出一個文件夾列表讓他選,這時可以把這幾個文件夾放到最前面展示,算是小優化吧。
  4. 系統會時刻檢測數據變化,有新的照片這個數據庫會自動更新,不需干預。

視頻相冊

獲取視頻文件和上面基本一樣,不過改下查詢條件就行了,實際中有個問題:視頻封面的獲取。

首先視頻封面縮略圖在這個videothumbnails數據庫,照片縮略圖在thumbnails,對應到本地SD卡就是在sdcard/DCIM/.thumbnails/文件夾(有的設備可能不同)

PS:這個文件夾是隱藏的,so你知道你的手機為何存儲空間越來越小了吧,拍的照片縮略圖全在這兒。。。非常非常多

android,讀取相冊照片,讀取本地相冊,Android讀取本地照片

實際中發現讀取不到新錄制的視頻封面,需要手動調用一個方法,來生成這個封面然后才能在videothumbnails讀取到:

參考:http://stackoverflow.com/questions/27903264/how-to-get-the-video-thumbnail-path-and-not-the-bitmap

//videoId是這個視頻文件在數據庫的IDMediaStore.Video.Thumbnails.getThumbnail(getContentResolver(), videoId, MediaStore.Video.Thumbnails.MICRO_KIND, null);

并且這里封面和視頻不在一個數據庫,需要在兩個cursor來讀取

我這里獲取整個SD的mp4格式視頻,代碼段如下:

 /**  * 獲取手機中所有視頻的信息  */ private void getAllVideoInfos(){  new Thread(new Runnable() {   @Override   public void run() {    HashMap<String,List<MediaBean>> allPhotosTemp = new HashMap<>();//所有照片    Uri mImageUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;    String[] proj = { MediaStore.Video.Thumbnails._ID      , MediaStore.Video.Thumbnails.DATA      ,MediaStore.Video.Media.DURATION      ,MediaStore.Video.Media.SIZE      ,MediaStore.Video.Media.DISPLAY_NAME      ,MediaStore.Video.Media.DATE_MODIFIED};    Cursor mCursor = getContentResolver().query(mImageUri,      proj,      MediaStore.Video.Media.MIME_TYPE + "=?",      new String[]{"video/mp4"},      MediaStore.Video.Media.DATE_MODIFIED+" desc");    if(mCursor!=null){     while (mCursor.moveToNext()) {      // 獲取視頻的路徑      int videoId = mCursor.getInt(mCursor.getColumnIndex(MediaStore.Video.Media._ID));      String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Video.Media.DATA));      int duration = mCursor.getInt(mCursor.getColumnIndex(MediaStore.Video.Media.DURATION));      long size = mCursor.getLong(mCursor.getColumnIndex(MediaStore.Video.Media.SIZE))/1024; //單位kb      if(size<0){       //某些設備獲取size<0,直接計算       Log.e("dml","this video size < 0 " + path);       size = new File(path).length()/1024;      }      String displayName = mCursor.getString(mCursor.getColumnIndex(MediaStore.Video.Media.DISPLAY_NAME));      long modifyTime = mCursor.getLong(mCursor.getColumnIndex(MediaStore.Video.Media.DATE_MODIFIED));//暫未用到      //提前生成縮略圖,再獲取:http://stackoverflow.com/questions/27903264/how-to-get-the-video-thumbnail-path-and-not-the-bitmap      MediaStore.Video.Thumbnails.getThumbnail(getContentResolver(), videoId, MediaStore.Video.Thumbnails.MICRO_KIND, null);      String[] projection = { MediaStore.Video.Thumbnails._ID, MediaStore.Video.Thumbnails.DATA};      Cursor cursor = getContentResolver().query(MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI        , projection        , MediaStore.Video.Thumbnails.VIDEO_ID + "=?"        , new String[]{videoId+""}        , null);      String thumbPath = "";      while (cursor.moveToNext()){       thumbPath = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Thumbnails.DATA));      }      cursor.close();      // 獲取該視頻的父路徑名      String dirPath = new File(path).getParentFile().getAbsolutePath();      //存儲對應關系      if (allPhotosTemp.containsKey(dirPath)) {       List<MediaBean> data = allPhotosTemp.get(dirPath);       data.add(new MediaBean(MediaBean.Type.Video,path,thumbPath,duration,size,displayName));       continue;      } else {       List<MediaBean> data = new ArrayList<>();       data.add(new MediaBean(MediaBean.Type.Video,path,thumbPath,duration,size,displayName));       allPhotosTemp.put(dirPath,data);      }     }     mCursor.close();    }    //更新界面    runOnUiThread(new Runnable() {     @Override     public void run() {      //...     }    });   }  }).start(); }

后記

其實Android已經提供叫做CursorLoader的API做這個事情,不需要手動new 工作線程,使用起來很簡單有需要可以對上面代碼改造。

android,讀取相冊照片,讀取本地相冊,Android讀取本地照片

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 东明县| 德州市| 麻栗坡县| 惠来县| 新疆| 铜梁县| 巴林左旗| 巫溪县| 高州市| 西安市| 天等县| 定西市| 大埔区| 伊金霍洛旗| 察雅县| 鹤峰县| 正蓝旗| 金昌市| 建湖县| 尼勒克县| 龙里县| 泽州县| 石狮市| 水富县| 临漳县| 新竹县| 太和县| 泌阳县| 六盘水市| 静海县| 英吉沙县| 烟台市| 葫芦岛市| 昔阳县| 巴青县| 湘西| 礼泉县| 施甸县| 巴青县| 新密市| 黎川县|