Android獲取手機圖片

1.概述

在Andorid系統中所有的文件路徑都保存在一個數據庫中,位於data/data/com.android.providers.media文件夾下的external.db

裏面的files表就有我們需要的內容,這個表包含了機器所有的文件。接下來只要選擇合適的sql語句來獲取我們需要的內容就行了。

2.實現

數據庫結構如下圖

首先過濾出相冊文件夾,獲取所在文件夾路徑,文件夾名稱,文件夾文件數目,文件路徑和修改時間。構建文件夾和封面

public static Cursor getAlbumCursor(ContentResolver cr){
//打開files這個表
        Uri uri= MediaStore.Files.getContentUri("external");
        String [] project =new String[]{
                MediaStore.Files.FileColumns.PARENT,
                MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
                "count(*)",
                MediaStore.Images.Media.DATA,
                "max(" + MediaStore.Images.Media.DATE_MODIFIED + ")"
        };
//用group by進行整合
        String selection = String.format("%s=? or %s=?) group by (%s",
                MediaStore.Files.FileColumns.MEDIA_TYPE,
                MediaStore.Files.FileColumns.MEDIA_TYPE,
                MediaStore.Files.FileColumns.PARENT
        ) ;
        String[] selectionArgs = new String[]{
                MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE+"",//獲取圖片文件
                MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO+"",//獲取視頻文件
        };
        String sortOrder = MediaStore.Images.Media.DATE_MODIFIED + " desc";
//        String sortOrder = "max(date_modified) DESC";
// 轉換成sql語句: SELECT parent, bucket_display_name, count(*), _data, max(date_modified) FROM files WHERE (media_type=? or media_type=?)
// group by (parent) HAVING (_data NOT LIKE ? ) ORDER BY max(date_modified) DESC
        return cr.query(uri,project,selection,selectionArgs,sortOrder);
    }

拿到cursor後就可以進行查詢獲取數據

 public Album(Cursor cur) {
//圖片路徑
        this(cur.getString(3),
//所在文件夾的名稱
                cur.getString(1),
//所在的父文件
                cur.getLong(0),
//文件夾的文件數目
                cur.getInt(2),
//修改時間
                cur.getLong(4)
        );
    }

相冊文件夾構建好了後,在來獲取文件夾裏面的所有的圖片

 public static Cursor getMediaCursor(ContentResolver cr,Album album){
        Uri uri = MediaStore.Files.getContentUri("external");
         String[] sProjection = new String[] {
                MediaStore.Images.Media.DATA,
                MediaStore.Images.Media.DATE_TAKEN,
                MediaStore.Images.Media.MIME_TYPE,
                MediaStore.Images.Media.SIZE,
                MediaStore.Images.Media.ORIENTATION
        };
//獲取parent一樣的文件
         String selections = (String.format("(%s=? or %s=?) and %s=?",
                 MediaStore.Files.FileColumns.MEDIA_TYPE,
                 MediaStore.Files.FileColumns.MEDIA_TYPE,
                 MediaStore.Files.FileColumns.PARENT));
        String[] selectionArgs = new String[]{
                MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE+"",
                MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO+"",
                album.getId()+""
        };
        String sortOrder = MediaStore.Images.Media.DATE_MODIFIED + " desc";
        return  cr.query(uri,sProjection,selections,selectionArgs,sortOrder);
    }

接下來構建實體類

 public Media(Cursor cur) {
//具體路徑
        this(cur.getString(0),
                cur.getLong(1),
                cur.getString(2),
                cur.getLong(3),
                cur.getInt(4));
    }

這種方式主要是利用好了sql語句,同時結合rxjava的話可以實現查詢一張照片顯示一張照片的效果。

3.擴展

類似的還可以獲取特定類型的文件

private ArrayList<LayoutElementParcelable> listImages() {
        ArrayList<LayoutElementParcelable> images = new ArrayList<>();
        final String[] projection = {MediaStore.Images.Media.DATA};
        final Cursor cursor = c.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection, null, null, null);
        if (cursor == null)
            return images;
        else if (cursor.getCount() > 0 && cursor.moveToFirst()) {
            do {
                String path = cursor.getString(cursor.getColumnIndex
                        (MediaStore.Files.FileColumns.DATA));
                HybridFileParcelable strings = RootHelper.generateBaseFile(new File(path), showHiddenFiles);
                if (strings != null) {
                    LayoutElementParcelable parcelable = createListParcelables(strings);
                    if(parcelable != null) images.add(parcelable);
                }
            } while (cursor.moveToNext());
        }
        cursor.close();
        return images;
    }

    private ArrayList<LayoutElementParcelable> listVideos() {
        ArrayList<LayoutElementParcelable> videos = new ArrayList<>();
        final String[] projection = {MediaStore.Images.Media.DATA};
        final Cursor cursor = c.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                projection, null, null, null);
        if (cursor == null)
            return videos;
        else if (cursor.getCount() > 0 && cursor.moveToFirst()) {
            do {
                String path = cursor.getString(cursor.getColumnIndex
                        (MediaStore.Files.FileColumns.DATA));
                HybridFileParcelable strings = RootHelper.generateBaseFile(new File(path), showHiddenFiles);
                if (strings != null) {
                    LayoutElementParcelable parcelable = createListParcelables(strings);
                    if(parcelable != null) videos.add(parcelable);
                }
            } while (cursor.moveToNext());
        }
        cursor.close();
        return videos;
    }

    private ArrayList<LayoutElementParcelable> listaudio() {
        String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
        String[] projection = {
                MediaStore.Audio.Media.DATA
        };

        Cursor cursor = c.getContentResolver().query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                projection,
                selection,
                null,
                null);

        ArrayList<LayoutElementParcelable> songs = new ArrayList<>();
        if (cursor == null)
            return songs;
        else if (cursor.getCount() > 0 && cursor.moveToFirst()) {
            do {
                String path = cursor.getString(cursor.getColumnIndex
                        (MediaStore.Files.FileColumns.DATA));
                HybridFileParcelable strings = RootHelper.generateBaseFile(new File(path), showHiddenFiles);
                if (strings != null) {
                    LayoutElementParcelable parcelable = createListParcelables(strings);
                    if(parcelable != null) songs.add(parcelable);
                }
            } while (cursor.moveToNext());
        }
        cursor.close();
        return songs;
    }

    private ArrayList<LayoutElementParcelable> listDocs() {
        ArrayList<LayoutElementParcelable> docs = new ArrayList<>();
        final String[] projection = {MediaStore.Files.FileColumns.DATA};
        Cursor cursor = c.getContentResolver().query(MediaStore.Files.getContentUri("external"),
                projection, null, null, null);
        String[] types = new String[]{".pdf", ".xml", ".html", ".asm", ".text/x-asm", ".def", ".in", ".rc",
                ".list", ".log", ".pl", ".prop", ".properties", ".rc",
                ".doc", ".docx", ".msg", ".odt", ".pages", ".rtf", ".txt", ".wpd", ".wps"};
        if (cursor == null)
            return docs;
        else if (cursor.getCount() > 0 && cursor.moveToFirst()) {
            do {
                String path = cursor.getString(cursor.getColumnIndex
                        (MediaStore.Files.FileColumns.DATA));
                if (path != null && Arrays.asList(types).contains(path)) {
                    HybridFileParcelable strings = RootHelper.generateBaseFile(new File(path), showHiddenFiles);
                    if (strings != null) {
                        LayoutElementParcelable parcelable = createListParcelables(strings);
                        if(parcelable != null) docs.add(parcelable);
                    }
                }
            } while (cursor.moveToNext());
        }
        cursor.close();
        Collections.sort(docs, (lhs, rhs) -> -1 * Long.valueOf(lhs.date).compareTo(rhs.date));
        if (docs.size() > 20)
            for (int i = docs.size() - 1; i > 20; i--) {
                docs.remove(i);
            }
        return docs;
    }

    private ArrayList<LayoutElementParcelable> listApks() {
        ArrayList<LayoutElementParcelable> apks = new ArrayList<>();
        final String[] projection = {MediaStore.Files.FileColumns.DATA};

        Cursor cursor = c.getContentResolver()
                .query(MediaStore.Files.getContentUri("external"), projection, null, null, null);
        if (cursor == null)
            return apks;
        else if (cursor.getCount() > 0 && cursor.moveToFirst()) {
            do {
                String path = cursor.getString(cursor.getColumnIndex
                        (MediaStore.Files.FileColumns.DATA));
                if (path != null && path.endsWith(".apk")) {
                    HybridFileParcelable strings = RootHelper.generateBaseFile(new File(path), showHiddenFiles);
                    if (strings != null) {
                        LayoutElementParcelable parcelable = createListParcelables(strings);
                        if(parcelable != null) apks.add(parcelable);
                    }
                }
            } while (cursor.moveToNext());
        }
        cursor.close();
        return apks;
    }

源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章