代码片段分享

android 10(Q, api29), getContent

2020-02-06  本文已影响0人  花艺荣

做本地图库,通过getContentResolver方法获取媒体文件,

 private final static String[] QUERY_Columns = {
            MediaStore.Files.FileColumns.DATA + " FROM (SELECT *"
    };
 getContentResolver().query(
                MediaStore.Files.getContentUri("external"),
                QUERY_Columns, ...

在android10(Q)上遇到crash:
Error : java.lang.IllegalArgumentException: Invalid column _data FROM (SELECT * at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:170) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140) at android.content.ContentProviderProxy.query(ContentProviderNative.java:423) at android.content.ContentResolver.query(ContentResolver.java:951) at android.content.ContentResolver.query(ContentResolver.java:887) at android.content.ContentResolver.query(ContentResolver.java:843) at com.dhq.album.model.ImageScannerModelImpl2.startScanImage2(ImageScannerModelImpl2.java:69) at com.dhq.album.ui.fragment.OneAlbumFolderFragment2$2.run(OneAlbumFolderFragment2.java:181) at java.lang.Thread.run(Thread.java:919)

问题在于:
MediaStore.Files.FileColumns.DATAMediaStore.Files.FileColumns.DATA 在 android 10(Q,api29)会不能被访问
/** * Path to the file on disk. * <p> * Note that apps may not have filesystem permissions to directly access * this path. Instead of trying to open this path directly, apps should * use {@link ContentResolver#openFileDescriptor(Uri, String)} to gain * access. * <p> * Type: TEXT */ public static final String DATA = "_data";

但是,我target api设的是28(android 9),为什么会有问题的?不管了,既然String path拿不到,就用它文档建议的获取uri,再去解析一下。
文档:
https://developer.android.com/training/data-storage/shared/media#java
如video:

class Video {
    private final Uri uri;
    private final String name;
    private final int duration;
    private final int size;

    public Video(Uri uri, String name, int duration, int size) {
        this.uri = uri;
        this.name = name;
        this.duration = duration;
        this.size = size;
    }
}
List<Video> videoList = new ArrayList<Video>();

String[] projection = new String[] {
    MediaStore.Video.Media._ID,
    MediaStore.Video.Media.DISPLAY_NAME,
    MediaStore.Video.Media.DURATION,
    MediaStore.Video.Media.SIZE
};
String selection = MediaStore.Video.Media.DURATION +
        " >= ?";
String[] selectionArgs = new String[] {
    String.valueOf(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES));
};
String sortOrder = MediaStore.Video.Media.DISPLAY_NAME + " ASC";

try (Cursor cursor = getApplicationContext().getContentResolver().query(
    MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
    projection,
    selection,
    selectionArgs,
    sortOrder
)) {
    // Cache column indices.
    int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
    int nameColumn =
            cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME);
    int durationColumn =
            cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION);
    int sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE);

    while (cursor.moveToNext()) {
        // Get values of columns for a given video.
        long id = cursor.getLong(idColumn);
        String name = cursor.getString(nameColumn);
        int duration = cursor.getInt(durationColumn);
        int size = cursor.getInt(sizeColumn);

        Uri contentUri = ContentUris.withAppendedId(
                MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id);

        // Stores column values and the contentUri in a local object
        // that represents the media file.
        videoList.add(new Video(contentUri, name, duration, size));
    }
}
上一篇下一篇

猜你喜欢

热点阅读