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