Skip to content

Commit

Permalink
gallery loader
Browse files Browse the repository at this point in the history
  • Loading branch information
REBOOTERS committed Mar 4, 2024
1 parent dbc1a9b commit dc3b0be
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2014 nohana, Inc.
* Copyright 2017 Zhihu Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package home.smart.fly.animations.internal.loader;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;

import androidx.loader.content.CursorLoader;

/**
* Load images and videos into a single cursor.
*/
public class AlbumMediaLoader extends CursorLoader {
private static final Uri QUERY_URI = MediaStore.Files.getContentUri("external");
private static final String[] PROJECTION = {MediaStore.Files.FileColumns._ID, MediaStore.MediaColumns.DISPLAY_NAME,
MediaStore.MediaColumns.DATE_ADDED, MediaStore.MediaColumns.MIME_TYPE, MediaStore.MediaColumns.SIZE, "duration"};
private static final String SELECTION_ALL_FOR_SINGLE_MEDIA_TYPE = MediaStore.Files.FileColumns.MEDIA_TYPE + "=?" + " AND " + MediaStore.MediaColumns.SIZE + ">0";

private static String[] getSelectionArgsForSingleMediaType(int mediaType) {
return new String[]{String.valueOf(mediaType)};
}

private static final String ORDER_BY = MediaStore.Images.Media.DATE_ADDED + " DESC";


private AlbumMediaLoader(Context context, String selection, String[] selectionArgs) {
super(context, QUERY_URI, PROJECTION, selection, selectionArgs, ORDER_BY);
}

public static CursorLoader newInstance(Context context) {
String selection = SELECTION_ALL_FOR_SINGLE_MEDIA_TYPE;
String[] selectionArgs = getSelectionArgsForSingleMediaType(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE);
return new AlbumMediaLoader(context, selection, selectionArgs);
}

@Override
public Cursor loadInBackground() {
return super.loadInBackground();
}

@Override
public void onContentChanged() {
// FIXME a dirty way to fix loading multiple times
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package home.smart.fly.animations.internal.loader

import android.net.Uri

data class GalleryPhoto(
val uri: Uri, val path: String, val size: String, val mimeType: String, val dateAdd: String
)
Original file line number Diff line number Diff line change
@@ -1,17 +1,109 @@
package home.smart.fly.animations.ui.activity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.PermissionChecker;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;

import com.zhihu.matisse.internal.utils.PathUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.Function;

import home.smart.fly.animations.R;
import home.smart.fly.animations.internal.loader.AlbumMediaLoader;
import home.smart.fly.animations.internal.loader.GalleryPhoto;
import home.smart.fly.animations.utils.SysUtil;

public class LoaderActivity extends AppCompatActivity {
public class LoaderActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = "LoaderActivity";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loaderctivity);
setSupportActionBar(findViewById(R.id.toolbar));

handlePermission();
}

private void handlePermission() {
String[] permissions;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
permissions = new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO};
} else {
permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
}

ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), o -> {
boolean allDone = true;

for (Boolean value : o.values()) {
if (!value) {
allDone = false;
break;
}
}
if (allDone) {
LoaderManager.getInstance(LoaderActivity.this).initLoader(101, null, LoaderActivity.this);
}
});
if (PermissionChecker.checkSelfPermission(this, Arrays.toString(permissions)) == PermissionChecker.PERMISSION_GRANTED) {
LoaderManager.getInstance(LoaderActivity.this).initLoader(101, null, LoaderActivity.this);
} else {
launcher.launch(permissions);
}
}

@NonNull
@Override
public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
return AlbumMediaLoader.newInstance(this);
}

@Override
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
ArrayList<Uri> uriList = new ArrayList<>();
if (data.moveToFirst()) {
do {
Uri uri = getUri(data);
uriList.add(uri);
} while (data.moveToNext());
}
Log.d(TAG, "total = " + uriList.size());
}

@Override
public void onLoaderReset(@NonNull Loader<Cursor> loader) {

}

@SuppressLint("Range")
private Uri getUri(Cursor cursor) {
long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID));
String mimeType = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE));
String size = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.SIZE));
String dateAdd = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATE_ADDED));
Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Uri uri = ContentUris.withAppendedId(contentUri, id);
String path = PathUtils.getPath(this, uri);
GalleryPhoto photo = new GalleryPhoto(uri, path, size, mimeType, SysUtil.timeStampToDate(dateAdd));
Log.d(TAG, "photo " + photo);
return uri;
}
}
14 changes: 14 additions & 0 deletions app/src/main/java/home/smart/fly/animations/utils/SysUtil.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package home.smart.fly.animations.utils

import android.os.Build
import java.text.SimpleDateFormat
import java.util.Date

/**
* @author rookie
Expand All @@ -12,4 +14,16 @@ object SysUtil {
fun Android8OrLater(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.O
}

@JvmStatic
fun timeStampToDate(timeInSeconds: String): String {
return timeStampToDate(timeInSeconds.toLong() * 100)
}

@JvmStatic
fun timeStampToDate(timeInMillionSeconds: Long): String {
val format = "yyyy-MM-dd HH:mm:ss"
val sdf = SimpleDateFormat(format)
return sdf.format(Date(timeInMillionSeconds))
}
}

0 comments on commit dc3b0be

Please sign in to comment.