Obtenir la liste des galeries de photos sur Android
je suis à la recherche d': Une liste des noms des galeries de photos existantes (avec un peu de chance leur vignette en haut aussi bien) Le contenu de la galerie (je peux alors charger des vignettes et des tailles complètes au besoin)
Comment puis-je obtenir une liste des "Galeries" (je ne sais pas si c'est le bon terme dans android pour les groupements d'images visibles dans l'application Galerie...) et leur contenu? J'ai besoin d'accéder à la galerie dans sa structure sans utiliser l'affichage de la galerie existante (je crée un totalement nouveau, pas un calque de la photo demandeur etc.)
je suppose MediaStore.Les Images sont là où je dois être mais je ne vois rien qui me donnera les regroupements...
5 réponses
les regroupements sont définis par MediaStore.Images.Media.BUCKET_DISPLAY_NAME
. Voici le code d'exemple pour lister les images et enregistrer leur nom de seau et date_taken:
// which image properties are we querying
String[] projection = new String[] {
MediaStore.Images.Media._ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.DATE_TAKEN
};
// content:// style URI for the "primary" external storage volume
Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
// Make the query.
Cursor cur = managedQuery(images,
projection, // Which columns to return
null, // Which rows to return (all rows)
null, // Selection arguments (none)
null // Ordering
);
Log.i("ListingImages"," query count=" + cur.getCount());
if (cur.moveToFirst()) {
String bucket;
String date;
int bucketColumn = cur.getColumnIndex(
MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
int dateColumn = cur.getColumnIndex(
MediaStore.Images.Media.DATE_TAKEN);
do {
// Get the field values
bucket = cur.getString(bucketColumn);
date = cur.getString(dateColumn);
// Do something with the values.
Log.i("ListingImages", " bucket=" + bucket
+ " date_taken=" + date);
} while (cur.moveToNext());
}
/**
* Getting All Images Path
*
* @param activity
* @return ArrayList with images Path
*/
public static ArrayList<String> getAllShownImagesPath(Activity activity) {
Uri uri;
Cursor cursor;
int column_index_data, column_index_folder_name;
ArrayList<String> listOfAllImages = new ArrayList<String>();
String absolutePathOfImage = null;
uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaColumns.DATA,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME };
cursor = activity.getContentResolver().query(uri, projection, null,
null, null);
column_index_data = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
column_index_folder_name = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
listOfAllImages.add(absolutePathOfImage);
}
return listOfAllImages;
}
Voici la solution complète en quelques étapes simples:
les prochaines étapes vous guideront pour créer un Vector
qui va contenir les albums trouvé sur un périphérique donné. Chaque Album contiendra une image de prévisualisation ainsi qu'un intérieur Vector
qui contiendra toutes les images de l'Album.
créer un objet qui retiendra les images Une fois extraites du stockage. Nous allons l'appeler
PhoneAlbum
. C'est la façon dont il va regardez:public class PhoneAlbum { private int id; private String name; private String coverUri; private Vector<PhonePhoto> albumPhotos; public int getId() { return id; } public void setId( int id ) { this.id = id; } public String getName() { return name; } public void setName( String name ) { this.name = name; } public String getCoverUri() { return coverUri; } public void setCoverUri( String albumCoverUri ) { this.coverUri = albumCoverUri; } public Vector< PhonePhoto > getAlbumPhotos() { if ( albumPhotos == null ) { albumPhotos = new Vector<>(); } return albumPhotos; } public void setAlbumPhotos( Vector< PhonePhoto > albumPhotos ) { this.albumPhotos = albumPhotos; } }
Créer un objet qui va contenir les images dans l'album intitulé:
PhonePhoto
public class PhonePhoto { private int id; private String albumName; private String photoUri; public int getId() { return id; } public void setId( int id ) { this.id = id; } public String getAlbumName() { return albumName; } public void setAlbumName( String name ) { this.albumName = name; } public String getPhotoUri() { return photoUri; } public void setPhotoUri( String photoUri ) { this.photoUri = photoUri; } }
créer une interface pour traiter les images extraites une fois terminées. Nous allons l'appeler
OnPhoneImagesObtained
. Ici, c'est:public interface OnPhoneImagesObtained { void onComplete( Vector<PhoneAlbum> albums ); void onError(); }
Créer une nouvelle classe:
DeviceImageManager
public class DeviceImageManager { }
une Fois que vous avez créé
DeviceImageManager
, ajouter ce qui suit: méthode:public static void getPhoneAlbums( Context context , OnPhoneImagesObtained listener ){ // Creating vectors to hold the final albums objects and albums names Vector< PhoneAlbum > phoneAlbums = new Vector<>(); Vector< String > albumsNames = new Vector<>(); // which image properties are we querying String[] projection = new String[] { MediaStore.Images.Media.BUCKET_DISPLAY_NAME, MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID }; // content: style URI for the "primary" external storage volume Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; // Make the query. Cursor cur = context.getContentResolver().query(images, projection, // Which columns to return null, // Which rows to return (all rows) null, // Selection arguments (none) null // Ordering ); if ( cur != null && cur.getCount() > 0 ) { Log.i("DeviceImageManager"," query count=" + cur.getCount()); if (cur.moveToFirst()) { String bucketName; String data; String imageId; int bucketNameColumn = cur.getColumnIndex( MediaStore.Images.Media.BUCKET_DISPLAY_NAME); int imageUriColumn = cur.getColumnIndex( MediaStore.Images.Media.DATA); int imageIdColumn = cur.getColumnIndex( MediaStore.Images.Media._ID ); do { // Get the field values bucketName = cur.getString( bucketNameColumn ); data = cur.getString( imageUriColumn ); imageId = cur.getString( imageIdColumn ); // Adding a new PhonePhoto object to phonePhotos vector PhonePhoto phonePhoto = new PhonePhoto(); phonePhoto.setAlbumName( bucketName ); phonePhoto.setPhotoUri( data ); phonePhoto.setId( Integer.valueOf( imageId ) ); if ( albumsNames.contains( bucketName ) ) { for ( PhoneAlbum album : phoneAlbums ) { if ( album.getName().equals( bucketName ) ) { album.getAlbumPhotos().add( phonePhoto ); Log.i( "DeviceImageManager", "A photo was added to album => " + bucketName ); break; } } } else { PhoneAlbum album = new PhoneAlbum(); Log.i( "DeviceImageManager", "A new album was created => " + bucketName ); album.setId( phonePhoto.getId() ); album.setName( bucketName ); album.setCoverUri( phonePhoto.getPhotoUri() ); album.getAlbumPhotos().add( phonePhoto ); Log.i( "DeviceImageManager", "A photo was added to album => " + bucketName ); phoneAlbums.add( album ); albumsNames.add( bucketName ); } } while (cur.moveToNext()); } cur.close(); listener.onComplete( phoneAlbums ); } else { listener.onError(); } }
il ne vous reste plus qu'à afficher les images à l'écran. Dans mon cas, j'aime utiliser
Picasso
. Voici comment je le fais:Picasso.with( getActivity() ) .load( "file:" + mPhoneAlbums.get( i ).getCoverUri() ) .centerCrop() .fit() .placeholder( R.drawable.temp_image ) .into( mAlbumPreview );
N'oubliez pas d'ajouter une permission pour lire le stockage externe dans votre manifeste:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
C'est ça. Tu es prêt à partir! Bonne chance!
Téléchargez le code source ici (obtenir toutes les images de la galerie dans android programmatically)
activity_main.xml
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
xmlns:android="http://schemas.android.com/apk/res/android">
<GridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/gv_folder"
android:numColumns="2"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"></GridView>
</RelativeLayout>
MainActivity.java
package galleryimages.galleryimages;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
public static ArrayList<Model_images> al_images = new ArrayList<>();
boolean boolean_folder;
Adapter_PhotosFolder obj_adapter;
GridView gv_folder;
private static final int REQUEST_PERMISSIONS = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gv_folder = (GridView)findViewById(R.id.gv_folder);
gv_folder.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getApplicationContext(), PhotosActivity.class);
intent.putExtra("value",i);
startActivity(intent);
}
});
if ((ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) && (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE))) {
} else {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
}else {
Log.e("Else","Else");
fn_imagespath();
}
}
public ArrayList<Model_images> fn_imagespath() {
al_images.clear();
int int_position = 0;
Uri uri;
Cursor cursor;
int column_index_data, column_index_folder_name;
String absolutePathOfImage = null;
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.MediaColumns.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
cursor = getApplicationContext().getContentResolver().query(uri, projection, null, null, orderBy + " DESC");
column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
column_index_folder_name = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
Log.e("Column", absolutePathOfImage);
Log.e("Folder", cursor.getString(column_index_folder_name));
for (int i = 0; i < al_images.size(); i++) {
if (al_images.get(i).getStr_folder().equals(cursor.getString(column_index_folder_name))) {
boolean_folder = true;
int_position = i;
break;
} else {
boolean_folder = false;
}
}
if (boolean_folder) {
ArrayList<String> al_path = new ArrayList<>();
al_path.addAll(al_images.get(int_position).getAl_imagepath());
al_path.add(absolutePathOfImage);
al_images.get(int_position).setAl_imagepath(al_path);
} else {
ArrayList<String> al_path = new ArrayList<>();
al_path.add(absolutePathOfImage);
Model_images obj_model = new Model_images();
obj_model.setStr_folder(cursor.getString(column_index_folder_name));
obj_model.setAl_imagepath(al_path);
al_images.add(obj_model);
}
}
for (int i = 0; i < al_images.size(); i++) {
Log.e("FOLDER", al_images.get(i).getStr_folder());
for (int j = 0; j < al_images.get(i).getAl_imagepath().size(); j++) {
Log.e("FILE", al_images.get(i).getAl_imagepath().get(j));
}
}
obj_adapter = new Adapter_PhotosFolder(getApplicationContext(),al_images);
gv_folder.setAdapter(obj_adapter);
return al_images;
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_PERMISSIONS: {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults.length > 0 && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
fn_imagespath();
} else {
Toast.makeText(MainActivity.this, "The app was not allowed to read or write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
}
}
}
}
}
}
j'ai trouvé un moyen d'obtenir des albums sans itération sur chaque photo.
String[] projection = new String[]{
"COUNT(*) as count",
MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
MediaStore.Images.ImageColumns.DATA,
"MAX (" + MediaStore.Images.ImageColumns.DATE_TAKEN + ") as max"};
Context context = ServiceProvider.getInstance().getApplicationContext();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection,
"1) GROUP BY (" + MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
null,
"max DESC");
curseur contiendra autant d'éléments, que le nom de seau distinct existe, et aussi vous pouvez obtenir le nombre à l'intérieur de chaque position de curseur pour obtenir le nombre d'images à l'intérieur de l'album
ici par exemple:
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
//gets image path, it will always be a latest image because of sortOrdering by MAX date_taken
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
//gets count via alias ("as count" in projection)
int count = cursor.getInt(cursor.getColumnIndex("count"));
//do you logic here
...
} while (cursor.moveToNext());
}
cursor.close();
}
Quelques explications sur la sélection param:
contentResolver ajoute des parenthèses lors de la compilation de la requête résultante pour sqlLite, donc si nous faisons une sélection comme
"GROUP BY" + MediaStore.Image.ImageColumns.BUCKET_DISPLAY_NAME
il sera compilé comme "WHERE (GROUP BY bucket_display_name)" et causera SQLiteException à l'exécution. Autrement si nous faisons la sélection comme
"1) GROUP BY (" + MediaStore.Image.ImageColumns.BUCKET_DISPLAY_NAME
il sera compilé comme" WHERE (1) GROUP BY (bucket_display_name)", ce qui est correct