Mostrando postagens com marcador Gallery. Mostrar todas as postagens
Mostrando postagens com marcador Gallery. Mostrar todas as postagens

domingo, 21 de agosto de 2011

Galeria de mídia do Android

Olá povo,

Neste post vou mostrar como tirar uma foto com a aplicação de câmera, salvar a imagem em um diretório temporário e em seguida adiciona-la à galeria de mídia do aparelho. E por último, vou mostrar como carregar uma imagem da galeria.
Vamos iniciar mostrando como chamar a aplicação de câmera.
public void tirarFotoClick(View v) {
  String nomeFoto = DateFormat.format(
    "yyyy-MM-dd_hhmmss", new Date()).toString();

  caminhoFoto = new File(
    Environment.getExternalStoragePublicDirectory(
      Environment.DIRECTORY_PICTURES),
    nomeFoto);

  Intent it = new Intent(
    MediaStore.ACTION_IMAGE_CAPTURE);  
  it.putExtra(MediaStore.EXTRA_OUTPUT, 
    Uri.fromFile(caminhoFoto));
  startActivityForResult(it, 0);
}
A aplicação de câmera é chamada através da ação ACTION_IMAGE_CAPTURE passado no construtor da Intent. Um detalhe interessante aqui é o parâmetro EXTRA_OUTPUT, ele serve para indicar um caminho para a foto ser salva. Sem ele, a imagem será salva com tamanho e qualidade inferior a que a câmera realmente tirou.

caminhoFoto é um atributo do tipo File.
A chamada do método startActivityForResult indica que queremos tratar o resultado da activity que estamos chamando. Esse tratamento é feito no método onActivityResult.
protected void onActivityResult(
  int requestCode, int resultCode, Intent data) {
  super.onActivityResult(
    requestCode, resultCode, data);

  if (resultCode == RESULT_OK && requestCode == 0) {
    ImageView img = (ImageView)
      findViewById(R.id.imageView1);
   
    // Obtém o tamanho da ImageView
    int targetW = img.getWidth();
    int targetH = img.getHeight();
    
    // Obtém a largura e altura da foto
    BitmapFactory.Options bmOptions =
      new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(
      caminhoFoto.getAbsolutePath(), bmOptions);

    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;
    
    // Determina o fator de redimensionamento
    int scaleFactor = Math.min(
      photoW/targetW, photoH/targetH);
    
    // Decodifica o arquivo de imagem em 
    // um Bitmap que preencherá a ImageView
    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;
    bmOptions.inPurgeable = true;
    
    Bitmap bitmap = BitmapFactory.decodeFile(
      caminhoFoto.getAbsolutePath(), bmOptions);
    img.setImageBitmap(bitmap);
  }
}
Quando chamamos a câmera, no startActivityForResult, passamos o valor 1 como segundo parâmetro, esse valor representa o código da requisição (requestCode). Esse valor é retornado no método onActivityResult para saber se o resultado que estamos tratando é daquela requisição. No if que fizemos, além do requestCode, checamos o resultCode. O resultCode descreve o resultado da operação, que neste caso é tirar a foto. Se o resultado for RESULT_OK, é porque uma foto foi tirada.
[EDITADO em 12/05/2013] 
A foto que é tirada com as câmeras atuais requer muita memória para ser alocada. Sendo assim, verificamos o tamanho da ImageView para carregar a imagem deste tamanho.
O atributo caminhoFoto que foi atribuído no método tirarFotoClick é utilizado para carregar a imagem e atribuir em um ImageView. Agora vamos ver como salvar essa imagem na galeria de mídia.
public void salvarFotoClick(View v) {
  if (caminhoFoto != null && caminhoFoto.exists()) {
    MediaStore.Images.Media.insertImage(
      getContentResolver(), 
      caminhoFoto.getAbsolutePath(), 
      caminhoFoto.getName(), "");

    Toast.makeText(this, 
      "Imagem adicionada a galeria.",
      Toast.LENGTH_SHORT).show();
  }
}
A classe MediaStore.Images.Media tem um "método mágico" que permite que possamos inserir um Bitmap na galeria. Essa operação é feita graças a um ContentProvider disponibilizado pela aplicação de galeria. O próximo passo será como abrir a galeria de mídia para selecionarmos uma imagem.
public void galleryButtonClick(View v) {

  Intent intent = new Intent(
    Intent.ACTION_GET_CONTENT);
  intent.setType("image/*");
  startActivityForResult(intent, 2);
}
O código acima abrirá a aplicação de galeria. Notem que agora passamos o valor 2 para o startActivityForResult. Da mesma forma que fizemos para tirar foto, usaremos o método onActivityResult para tratar a imagem selecionada.
// adicione esse código no onActivityResult
if (resultCode == RESULT_OK && requestCode == 2) {
  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 filePath = cursor.getString(columnIndex); 
  cursor.close();

  Bitmap yourSelectedImage = 
    BitmapFactory.decodeFile(filePath);

  imageView1.setImageBitmap(yourSelectedImage);
}
A galeria retorna o endereço da imagem selecionada através de um objeto Uri que é obtido em data.getData(). Com essa informação podemos acessar o ContentProvider da galeria para obter o caminho da imagem. Com esse caminho passamos para a classe BitmapFactory que retornará um objeto Bitmap para preencher a imageView.

Qualquer dúvida, deixem seus comentários.

4br4ç05,
nglauber