Cette question avait été posée à l'origine pour Android 1.6.
Je travaille sur les options de photos dans mon application.
J'ai un bouton et un ImageView dans mon activité. Lorsque je clique sur le bouton, il est redirigé vers la galerie et je peux sélectionner une image. L'image sélectionnée apparaîtra dans mon ImageView.
Réponse mise à jour, presque 5 ans plus tard:
Le code de la réponse d'origine ne fonctionne plus de manière fiable, car les images de différentes sources renvoient parfois avec un URI de contenu différent, c'est-à-dire content://
plutôt que file://
. Une meilleure solution consiste simplement à utiliser context.getContentResolver().openInputStream(intent.getData())
, car cela renverra un InputStream que vous pourrez gérer à votre guise.
Par exemple, BitmapFactory.decodeStream()
fonctionne parfaitement dans cette situation, car vous pouvez également utiliser les champs Options et inSampleSize pour sous-échantillonner des images volumineuses et éviter les problèmes de mémoire.
Cependant, des éléments tels que Google Drive renvoient des URI à des images qui n'ont pas encore été téléchargées. Par conséquent, vous devez exécuter le code getContentResolver () sur un thread en arrière-plan.
Réponse originale:
Les autres réponses expliquaient comment envoyer l'intention, mais elles n'expliquaient pas bien comment gérer la réponse. Voici un exemple de code sur la façon de le faire:
protected void onActivityResult(int requestCode, int resultCode,
Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case REQ_CODE_PICK_IMAGE:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(
selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
Bitmap yourSelectedImage = BitmapFactory.decodeFile(filePath);
}
}
}
Après cela, vous avez l'image sélectionnée stockée dans "yourSelectedImage" pour faire ce que vous voulez. Ce code fonctionne en obtenant l'emplacement de l'image dans la base de données ContentResolver, mais cela ne suffit pas. Chaque image contient environ 18 colonnes d'informations, allant de son chemin d'accès au fichier à la "date de la dernière modification", en passant par les coordonnées GPS de l'endroit où la photo a été prise, bien que de nombreux champs ne soient pas réellement utilisés.
Pour gagner du temps car vous n'avez pas réellement besoin des autres champs, la recherche du curseur est effectuée à l'aide d'un filtre. Le filtre fonctionne en spécifiant le nom de la colonne souhaitée, MediaStore.Images.Media.DATA, qui est le chemin d'accès, puis en donnant cette chaîne [] à la requête du curseur. La requête de curseur retourne avec le chemin, mais vous ne savez pas dans quelle colonne elle se trouve jusqu'à ce que vous utilisiez le code columnIndex
. Cela donne simplement le numéro de la colonne en fonction de son nom, le même que celui utilisé dans le processus de filtrage. Une fois que vous avez cela, vous êtes enfin capable de décoder l'image en un bitmap avec la dernière ligne de code que j'ai donnée.
private static final int SELECT_PHOTO = 100;
Intention de départ
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
Résultat du processus
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case SELECT_PHOTO:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
InputStream imageStream = getContentResolver().openInputStream(selectedImage);
Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream);
}
}
}
Vous pouvez également sous-échantillonner votre image pour éviter les erreurs OutOfMemory.
private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 140;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE) {
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);
}
Vous devez démarrer l'intention de la galerie pour obtenir un résultat.
Intent i = new Intent(Intent.ACTION_PICK,
Android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, ACTIVITY_SELECT_IMAGE);
Ensuite, dans onActivityForResult
, appelez intent.getData()
pour obtenir l'URI de l'image. Ensuite, vous devez obtenir l'image auprès de ContentProvider.
Voici un code testé pour les images et les vidéos.Il fonctionnera également pour toutes les API de moins de 19 ans et de plus de 19 ans.
Image:
if (Build.VERSION.SDK_INT <= 19) {
Intent i = new Intent();
i.setType("image/*");
i.setAction(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(i, 10);
} else if (Build.VERSION.SDK_INT > 19) {
Intent intent = new Intent(Intent.ACTION_PICK, Android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 10);
}
Vidéo:
if (Build.VERSION.SDK_INT <= 19) {
Intent i = new Intent();
i.setType("video/*");
i.setAction(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(i, 20);
} else if (Build.VERSION.SDK_INT > 19) {
Intent intent = new Intent(Intent.ACTION_PICK, Android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 20);
}
.
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 10) {
Uri selectedImageUri = data.getData();
String selectedImagePath = getRealPathFromURI(selectedImageUri);
} else if (requestCode == 20) {
Uri selectedVideoUri = data.getData();
String selectedVideoPath = getRealPathFromURI(selectedVideoUri);
}
}
}
public String getRealPathFromURI(Uri uri) {
if (uri == null) {
return null;
}
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
if (cursor != null) {
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
return uri.getPath();
}
Faites ceci pour lancer la galerie et permettre à l'utilisateur de choisir une image:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK);
Ensuite, dans votre onActivityResult()
, utilisez l'URI de l'image renvoyée pour définir l'image sur votre ImageView.
public class EMView extends Activity {
ImageView img,img1;
int column_index;
Intent intent=null;
// Declare our Views, so we can access them later
String logo,imagePath,Logo;
Cursor cursor;
//YOU CAN EDIT THIS TO WHATEVER YOU WANT
private static final int SELECT_PICTURE = 1;
String selectedImagePath;
//ADDED
String filemanagerstring;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
img= (ImageView)findViewById(R.id.gimg1);
((Button) findViewById(R.id.Button01))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// in onCreate or any event where your want the user to
// select a file
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}
});
}
//UPDATED
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
//OI FILE Manager
filemanagerstring = selectedImageUri.getPath();
//MEDIA GALLERY
selectedImagePath = getPath(selectedImageUri);
img.setImageURI(selectedImageUri);
imagePath.getBytes();
TextView txt = (TextView)findViewById(R.id.title);
txt.setText(imagePath.toString());
Bitmap bm = BitmapFactory.decodeFile(imagePath);
// img1.setImageBitmap(bm);
}
}
}
//UPDATED!
public String getPath(Uri uri) {
String[] projection = { MediaColumns.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
column_index = cursor
.getColumnIndexOrThrow(MediaColumns.DATA);
cursor.moveToFirst();
imagePath = cursor.getString(column_index);
return cursor.getString(column_index);
}
}
public class BrowsePictureActivity extends Activity {
private static final int SELECT_PICTURE = 1;
private String selectedImagePath;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((Button) findViewById(R.id.Button01))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
}
}
}
public String getPath(Uri uri) {
if( uri == null ) {
return null;
}
// this will only work for images selected from gallery
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if( cursor != null ){
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
return uri.getPath();
}
}
Pour certaines raisons, toutes les réponses de ce fil, dans onActivityResult()
, tentent de post-traiter le Uri
reçu, comme si vous obteniez le chemin réel de l'image, puis utilisez BitmapFactory.decodeFile(path)
pour obtenir le Bitmap
.
Cette étape est inutile. La classe ImageView
a une méthode appelée setImageURI(uri)
. Passez votre uri à cela et vous devriez avoir terminé.
Uri imageUri = data.getData();
imageView.setImageURI(imageUri);
Pour un exemple de travail complet, vous pouvez jeter un oeil ici: http://androidbitmaps.blogspot.com/2015/04/loading-images-in-Android-part-iii-pick.html
PS:
Obtenir la Bitmap
dans une variable distincte serait logique dans les cas où l'image à charger est trop grande pour tenir en mémoire, et une opération de réduction d'échelle est nécessaire pour éviter OurOfMemoryError
, comme indiqué dans la réponse @siamii.
appelez la méthode ChooseImage comme-
public void chooseImage(ImageView v)
{
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, SELECT_PHOTO);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
if(imageReturnedIntent != null)
{
Uri selectedImage = imageReturnedIntent.getData();
switch(requestCode) {
case SELECT_PHOTO:
if(resultCode == RESULT_OK)
{
Bitmap datifoto = null;
temp.setImageBitmap(null);
Uri picUri = null;
picUri = imageReturnedIntent.getData();//<- get Uri here from data intent
if(picUri !=null){
try {
datifoto = Android.provider.MediaStore.Images.Media.getBitmap(this.getContentResolver(), picUri);
temp.setImageBitmap(datifoto);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (OutOfMemoryError e) {
Toast.makeText(getBaseContext(), "Image is too large. choose other", Toast.LENGTH_LONG).show();
}
}
}
break;
}
}
else
{
//Toast.makeText(getBaseContext(), "data null", Toast.LENGTH_SHORT).show();
}
}
#initialize in main activity
path = Environment.getExternalStorageDirectory()
+ "/images/make_machine_example.jpg"; #
ImageView image=(ImageView)findViewById(R.id.image);
//--------------------------------------------------||
public void FromCamera(View) {
Log.i("camera", "startCameraActivity()");
File file = new File(path);
Uri outputFileUri = Uri.fromFile(file);
Intent intent = new Intent(
Android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 1);
}
public void FromCard() {
Intent i = new Intent(Intent.ACTION_PICK,
Android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, 2);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2 && resultCode == RESULT_OK
&& null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
bitmap = BitmapFactory.decodeFile(picturePath);
image.setImageBitmap(bitmap);
if (bitmap != null) {
ImageView rotate = (ImageView) findViewById(R.id.rotate);
}
} else {
Log.i("SonaSys", "resultCode: " + resultCode);
switch (resultCode) {
case 0:
Log.i("SonaSys", "User cancelled");
break;
case -1:
onPhotoTaken();
break;
}
}
}
protected void onPhotoTaken() {
// Log message
Log.i("SonaSys", "onPhotoTaken");
taken = true;
imgCapFlag = true;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
bitmap = BitmapFactory.decodeFile(path, options);
image.setImageBitmap(bitmap);
}