Nesse post rápido vou mostrar como carregar imagens da galeria de mídia do Android. O único detalhe a observar nesse post é que estamos carregando imagens tanto locais quando as que estão em algum serviço da nuvem como DropBox e Google Photos. Por isso, para começar coloque as permissões necessárias no AndroidManifest.xml.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET"/>Lembrando que para o Android 6 (API Level 23) você deve checar essas permissões em tempo de execução.
Em seguida, inicie uma nova activity utilizando a ação ACTION_GET_CONTENT.
private static final int IMAGE_GALLERY_REQUEST = 1;
...
public void selectImageClick(View view) {
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(
intent,
getString(R.string.select_picture_title)),
IMAGE_GALLERY_REQUEST);
} else {
ActivityCompat.requestPermissions(this,
new String[]{ Manifest.permission.READ_EXTERNAL_STORAGE },
IMAGE_GALLERY_REQUEST);
}
}
Ao selecionarmos uma imagem, o método onActivityResult será chamado.@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == IMAGE_GALLERY_REQUEST && resultCode == RESULT_OK){
new LoadImageTask(this).execute(data.getData());
}
}
Como falamos anteriormente, carregaremos as imagens do sistema de arquivos ou da web. Por isso, devemos realizar essa operação fora da UI thread, então definimos a classe LoadImageTask.
class LoadImageTask extends AsyncTask<Uri, Void, Bitmap> {
WeakReference<PickImageActivity> mActivity;
public LoadImageTask(PickImageActivity activity) {
this.mActivity = new WeakReference<>(activity);
}
public PickImageActivity getActivity() {
return mActivity.get();
}
@Override
protected Bitmap doInBackground(Uri... params) {
if (getActivity() != null) {
try {
return BitmapFactory.decodeStream(
getActivity().getContentResolver().openInputStream(params[0]));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (getActivity() != null){
getActivity().showImage(bitmap);
}
}
}
Temos algumas coisas interessantes aqui. A primeira é essa classe não deve ser uma inner class da Activity/Fragment, pois uma inner class sempre contém uma referência para sua outer class. Uma vez que ela não é uma inner class, devemos passar a referência da activity/fragment para essa classe. Estamos utilizando uma WeakReference para armazenar a instância da activity, o motivo disso é evitar o leak de memória, já que se o usuário sair da tela antes da imagem ser baixada aquela memória ficará alocada desnecessariamente durante algum tempo.Outra coisa interessante é que estamos utilizando o método openInputStream() da classe ContentResolver para obter a imagem propriamente dita.
A imagem retornada terá o seu tamanho original, se você preferir, pode utilizar a técnica de redimensionamento de imagem que eu mostrei nesse post.
Por fim, no onPostExecute, invocamos o método showImage da Activity.
public void showImage(Bitmap bitmap) {
ImageView imageView = (ImageView)findViewById(R.id.imageView);
if (imageView != null){
imageView.setImageBitmap(bitmap);
}
}
Qualquer dúvida, deixe seu comentário ;)4br4ç05,
nglauber
2 comentários:
Nelson, suas dicas são demais.
Já virei fã seu desde a primeira edição do seu livro.
Valeu Ueder,!
4br4ç05,
nglauber
Postar um comentário