可能包名不對,我用的是Androidx,請自行替換
package com.example.alioss.demo.myglide;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
/**
* A data model containing data for a single media item.
*/
public class MediaStoreData implements Parcelable {
public static final Creator<MediaStoreData> CREATOR = new Creator<MediaStoreData>() {
@Override
public MediaStoreData createFromParcel(Parcel parcel) {
return new MediaStoreData(parcel);
}
@Override
public MediaStoreData[] newArray(int i) {
return new MediaStoreData[i];
}
};
@Override
public int describeContents() {
return 0;
}
public final long rowId;
public final Uri uri;
public final String mimeType;
public final long dateModified;
public final int orientation;
public final Type type;
public final long dateTaken;
MediaStoreData(long rowId, Uri uri, String mimeType, long dateTaken, long dateModified,
int orientation, Type type) {
this.rowId = rowId;
this.uri = uri;
this.dateModified = dateModified;
this.mimeType = mimeType;
this.orientation = orientation;
this.type = type;
this.dateTaken = dateTaken;
}
private MediaStoreData(Parcel in) {
rowId = in.readLong();
uri = Uri.parse(in.readString());
mimeType = in.readString();
dateTaken = in.readLong();
dateModified = in.readLong();
orientation = in.readInt();
type = Type.valueOf(in.readString());
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeLong(rowId);
parcel.writeString(uri.toString());
parcel.writeString(mimeType);
parcel.writeLong(dateTaken);
parcel.writeLong(dateModified);
parcel.writeInt(orientation);
parcel.writeString(type.name());
}
@Override
public String toString() {
return "MediaStoreData{"
+ "rowId=" + rowId
+ ", uri=" + uri
+ ", mimeType='" + mimeType + '\''
+ ", dateModified=" + dateModified
+ ", orientation=" + orientation
+ ", type=" + type
+ ", dateTaken=" + dateTaken
+ '}';
}
/**
* The type of data.
*/
public enum Type {
VIDEO,
IMAGE,
}
}
package com.example.alioss.demo.myglide;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.loader.content.AsyncTaskLoader;
/**
* Loads metadata from the media store for images and videos.
*/
public class MediaStoreDataLoader extends AsyncTaskLoader<List<MediaStoreData>> {
private static final String[] IMAGE_PROJECTION =
new String[]{
MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATE_TAKEN,
MediaStore.Images.ImageColumns.DATE_MODIFIED,
MediaStore.Images.ImageColumns.MIME_TYPE,
MediaStore.Images.ImageColumns.ORIENTATION,
};
private static final String[] VIDEO_PROJECTION =
new String[]{
MediaStore.Video.VideoColumns._ID,
MediaStore.Video.VideoColumns.DATE_TAKEN,
MediaStore.Video.VideoColumns.DATE_MODIFIED,
MediaStore.Video.VideoColumns.MIME_TYPE,
"0 AS " + MediaStore.Images.ImageColumns.ORIENTATION,
};
private final ForceLoadContentObserver forceLoadContentObserver = new ForceLoadContentObserver();
private List<MediaStoreData> cached;
private boolean observerRegistered = false;
public MediaStoreDataLoader(@NonNull Context context) {
super(context);
}
@Override
protected void onStartLoading() {
if (cached != null) {
deliverResult(cached);
}
if (takeContentChanged() || cached == null) {
forceLoad();
}
registerContentObserver();
}
@Override
public void deliverResult(List<MediaStoreData> data) {
if (!isReset() && isStarted()) {
super.deliverResult(data);
}
}
private void registerContentObserver() {
if (!observerRegistered) {
ContentResolver cr = getContext().getContentResolver();
cr.registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false,
forceLoadContentObserver);
cr.registerContentObserver(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, false,
forceLoadContentObserver);
observerRegistered = true;
}
}
@Override
protected void onReset() {
super.onReset();
onStopLoading();
cached = null;
unregisterContentObserver();
}
@Override
protected void onStopLoading() {
cancelLoad();
}
private void unregisterContentObserver() {
if (observerRegistered) {
observerRegistered = false;
getContext().getContentResolver().unregisterContentObserver(forceLoadContentObserver);
}
}
@Override
protected void onAbandon() {
super.onAbandon();
unregisterContentObserver();
}
@Override
public List<MediaStoreData> loadInBackground() {
List<MediaStoreData> data = queryImages();
data.addAll(queryVideos());
Collections.sort(data, new Comparator<MediaStoreData>() {
@Override
public int compare(MediaStoreData mediaStoreData, MediaStoreData mediaStoreData2) {
return Long.valueOf(mediaStoreData2.dateTaken).compareTo(mediaStoreData.dateTaken);
}
});
return data;
}
private List<MediaStoreData> queryImages() {
return query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION,
MediaStore.Images.ImageColumns.DATE_TAKEN, MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATE_TAKEN, MediaStore.Images.ImageColumns.DATE_MODIFIED,
MediaStore.Images.ImageColumns.MIME_TYPE, MediaStore.Images.ImageColumns.ORIENTATION,
MediaStoreData.Type.IMAGE);
}
private List<MediaStoreData> queryVideos() {
return query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, VIDEO_PROJECTION,
MediaStore.Video.VideoColumns.DATE_TAKEN, MediaStore.Video.VideoColumns._ID,
MediaStore.Video.VideoColumns.DATE_TAKEN, MediaStore.Video.VideoColumns.DATE_MODIFIED,
MediaStore.Video.VideoColumns.MIME_TYPE, MediaStore.Images.ImageColumns.ORIENTATION,
MediaStoreData.Type.VIDEO);
}
private List<MediaStoreData> query(Uri contentUri, String[] projection, String sortByCol,
String idCol, String dateTakenCol, String dateModifiedCol, String mimeTypeCol,
String orientationCol, MediaStoreData.Type type) {
final List<MediaStoreData> data = new ArrayList<MediaStoreData>();
Cursor cursor = getContext().getContentResolver()
.query(contentUri, projection, null, null, sortByCol + " DESC");
if (cursor == null) {
return data;
}
try {
final int idColNum = cursor.getColumnIndexOrThrow(idCol);
final int dateTakenColNum = cursor.getColumnIndexOrThrow(dateTakenCol);
final int dateModifiedColNum = cursor.getColumnIndexOrThrow(dateModifiedCol);
final int mimeTypeColNum = cursor.getColumnIndex(mimeTypeCol);
final int orientationColNum = cursor.getColumnIndexOrThrow(orientationCol);
while (cursor.moveToNext()) {
long id = cursor.getLong(idColNum);
long dateTaken = cursor.getLong(dateTakenColNum);
String mimeType = cursor.getString(mimeTypeColNum);
long dateModified = cursor.getLong(dateModifiedColNum);
int orientation = cursor.getInt(orientationColNum);
data.add(new MediaStoreData(id, Uri.withAppendedPath(contentUri, Long.toString(id)),
mimeType, dateTaken, dateModified, orientation, type));
}
} finally {
cursor.close();
}
return data;
}
}
以下是調用的activity,繼承AppCompatActivity
package com.example.alioss;
import android.Manifest;
import android.os.Bundle;
import android.util.Log;
import com.example.alioss.demo.myglide.MediaStoreData;
import com.example.alioss.demo.myglide.MediaStoreDataLoader;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<MediaStoreData>> {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestStoragePermission();
LoaderManager.getInstance(this).initLoader(111,null,this);
}
private void requestStoragePermission() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
0);
}
@NonNull
@Override
public Loader<List<MediaStoreData>> onCreateLoader(int id, @Nullable Bundle args) {
return new MediaStoreDataLoader(this);
}
@Override
public void onLoadFinished(@NonNull Loader<List<MediaStoreData>> loader, List<MediaStoreData> data) {
for (MediaStoreData msd :
data) {
Log.i("11111111", "uri: "+msd.uri);
}
}
@Override
public void onLoaderReset(@NonNull Loader<List<MediaStoreData>> loader) {
}
}
initLoader的id可以自己定義,沒什麼好說的,都是套路