A possibilidade de utilizar a câmera do dispositivo para tirar fotos a partir de nosso próprio app Android é muito atraente e certamente será de grande importância para dezenas de aplicações.
Geralmente no Android há duas formas de realizar determinadas operações. Como exemplo podemos citar o envio de mensagens SMS. É possível chamar o aplicativo nativo de envio de SMS já passando como parâmetros destinatário e o assunto, e então o próprio aplicativo nativo envia a mensagem. Ou, alternativamente, pode-se fazer com que nosso próprio app envie o SMS. É uma questão de escolha. Neste tutorial ensinaremos a primeira abordagem, ou seja, utilizaremos o aplicativo padrão de câmera do dispositivo.
Embora possa parecer algo complicado numa primeira análise, na verdade é extremamente simples. Chamamos o aplicativo de câmera nativo do aparelho (informando o diretório onde desejamos que a foto seja gravada) e então, concluída a operação de obtenção da fotografia, lemos o arquivo JPG e mostramos na tela do nosso app.
Então vamos lá...
Primeiro vamos criar um projeto novo e chamá-lo de "fotografo". Depois vamos abrir o arquivo "AndroidManifest.xml" e acrescentar (após o elemento "<uses-sdk>") a seguinte permissão:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Isto fará com que nosso app possa gravar no cartão de memória do dispositivo (SDCARD).
Agora vamos abrir o arquivo "strings.xml" da pasta "res/values" e acrescentar os dois parâmetros abaixo, marcados em azul, para que fique assim:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">fotografo</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="resultado"></string>
<string name="textoBotaoTirarFoto">Fotografar</string>
</resources>
<resources>
<string name="app_name">fotografo</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="resultado"></string>
<string name="textoBotaoTirarFoto">Fotografar</string>
</resources>
O que estamos fazendo com isto é definir um campo de mensagens, para mostrar o resultado da operação e também o texto do botão que colocaremos na tela.
Em seguida vamos construir o layout da tela que apresentaremos ao usuário. Abramos portanto o arquivo "activity_main.xml", da pasta "res/layout" e substituamos pelo código abaixo:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textViewResultado"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/resultado" />
<LinearLayout
android:id="@+id/LayoutPrincipal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@+id/textViewResultado"
android:gravity="bottom|center_horizontal"
android:orientation="vertical" >
<ImageView
android:id="@+id/imageViewFoto"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_weight="0.67"
android:scaleType="center"
android:src="@drawable/preview" />
<Button
android:id="@+id/btnTirarFoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/imageViewFoto"
android:text="@string/textoBotaoTirarFoto" />
</LinearLayout>
</RelativeLayout>
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textViewResultado"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/resultado" />
<LinearLayout
android:id="@+id/LayoutPrincipal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@+id/textViewResultado"
android:gravity="bottom|center_horizontal"
android:orientation="vertical" >
<ImageView
android:id="@+id/imageViewFoto"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_weight="0.67"
android:scaleType="center"
android:src="@drawable/preview" />
<Button
android:id="@+id/btnTirarFoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/imageViewFoto"
android:text="@string/textoBotaoTirarFoto" />
</LinearLayout>
</RelativeLayout>
Aqui estamos acrescentando um "TextView", que utilizaremos para mostrar o resultado da operação de tirar a foto (textViewResultado). Também um "ImageView" , onde mostraremos a imagem da foto tirada (imageViewFoto). Por último, estamos incluindo um botão que será utilizado pelo usuário para chamar a operação de tirar a foto ("btnTirarFoto").
Faça o download da figura abaixo. Crie uma pasta sob o diretório "res" chamada "drawable". Grave esta imagem (preview.png) nesta pasta.
Agora a parte final. Vamos abrir o arquivo "MainActivity.java" da pasta "src" e substituir integralmente o código por este:
package com.example.fotografo;
import java.io.File;
import java.util.Random;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.view.View.OnClickListener;
public class MainActivity extends Activity
{
private static final int IMAGEM_VIA_CAMERA=0;
private Button btnTirarFoto;
private TextView textViewResultado;
private Intent intent;
private Bitmap mImageBitmap;
private Bitmap mImageBitmapThumb;
private ImageView imageViewFoto;
private String nomeDoArquivo;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Obtém os elementos da tela.
btnTirarFoto=(Button) findViewById(R.id.btnTirarFoto);
textViewResultado=(TextView) findViewById(R.id.textViewResultado);
imageViewFoto=(ImageView) findViewById(R.id.imageViewFoto);
// Adiciona listener ao botão.
addListenerOnButtonFotografar();
}
public void addListenerOnButtonFotografar()
{
// A função de um listener no botão é verificar se houve intervenção do usuário sobre ele.
// Aqui verificamos se o usuário clicou no botão e em caso afirmativo, tomamos uma ação.
btnTirarFoto.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// Configura e cria o diretório de gravação como "MinhasImagens" dentro do SDCARD.
File diretorioDeImagens = new File(Environment.getExternalStorageDirectory(), "MinhasImagens");
diretorioDeImagens.mkdirs();
// Cria um prefixo para o nome do arquivo.
Random r=new Random();
int prefixo=r.nextInt(10000) + 1;
// Constrói o nome do arquivo e informa onde o aplicativo de câmera deverá gravar a foto.
nomeDoArquivo = "imagem_" + prefixo + ".jpg";
File image = new File(diretorioDeImagens, nomeDoArquivo);
Uri uriSavedImage = Uri.fromFile(image);
// Chama o aplicativo de câmera do dispositivo e aguarda o resultado.
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(intent, IMAGEM_VIA_CAMERA);
import java.io.File;
import java.util.Random;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.view.View.OnClickListener;
public class MainActivity extends Activity
{
private static final int IMAGEM_VIA_CAMERA=0;
private Button btnTirarFoto;
private TextView textViewResultado;
private Intent intent;
private Bitmap mImageBitmap;
private Bitmap mImageBitmapThumb;
private ImageView imageViewFoto;
private String nomeDoArquivo;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Obtém os elementos da tela.
btnTirarFoto=(Button) findViewById(R.id.btnTirarFoto);
textViewResultado=(TextView) findViewById(R.id.textViewResultado);
imageViewFoto=(ImageView) findViewById(R.id.imageViewFoto);
// Adiciona listener ao botão.
addListenerOnButtonFotografar();
}
public void addListenerOnButtonFotografar()
{
// A função de um listener no botão é verificar se houve intervenção do usuário sobre ele.
// Aqui verificamos se o usuário clicou no botão e em caso afirmativo, tomamos uma ação.
btnTirarFoto.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// Configura e cria o diretório de gravação como "MinhasImagens" dentro do SDCARD.
File diretorioDeImagens = new File(Environment.getExternalStorageDirectory(), "MinhasImagens");
diretorioDeImagens.mkdirs();
// Cria um prefixo para o nome do arquivo.
Random r=new Random();
int prefixo=r.nextInt(10000) + 1;
// Constrói o nome do arquivo e informa onde o aplicativo de câmera deverá gravar a foto.
nomeDoArquivo = "imagem_" + prefixo + ".jpg";
File image = new File(diretorioDeImagens, nomeDoArquivo);
Uri uriSavedImage = Uri.fromFile(image);
// Chama o aplicativo de câmera do dispositivo e aguarda o resultado.
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(intent, IMAGEM_VIA_CAMERA);
// Note que "IMAGEM_VIA_CAMERA" é o nosso identificador (requestCode).
}
});
}
// Este método será chamado quando houver um resultado originário
}
});
}
// Este método será chamado quando houver um resultado originário
// de uma atividade previamente requisitada.
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
// requestCode é o identificador que permite identificar de onde veio a chamada.
if (requestCode == IMAGEM_VIA_CAMERA)
{
// Caso o usuário tenha tido êxito em tirar uma foto.
if (resultCode == RESULT_OK)
{
// Atualiza a caixa de mensagens.
textViewResultado.setText("Imagem gravada com sucesso");
// Lê a imagem gravada.
File sdcard = Environment.getExternalStorageDirectory();
mImageBitmap=BitmapFactory.decodeFile(sdcard+"/MinhasImagens/" + nomeDoArquivo);
// Gera um thumbnail.
Bitmap imagemRedimensionada=Bitmap.createScaledBitmap(mImageBitmap, 300, 200, false);
// Rotaciona a imagem em 90 graus.
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap imagemRotacionada = Bitmap.createBitmap(imagemRedimensionada , 0, 0, imagemRedimensionada.getWidth(), imagemRedimensionada.getHeight(), matrix, true);
// Mostra o thumbnail da foto na tela do app.
mImageBitmapThumb = imagemRotacionada;
imageViewFoto.setVisibility(View.VISIBLE);
imageViewFoto.setImageBitmap(mImageBitmapThumb);
}
else
{
// Atualiza mensagem de erro.
textViewResultado.setText("Operação cancelada pelo usuário");
// Restaura imagem original (de preview).
int id=getResources().getIdentifier("com.example.fotografo:drawable/preview", null, null);
imageViewFoto.setImageResource(id);
}
}
}
}
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
// requestCode é o identificador que permite identificar de onde veio a chamada.
if (requestCode == IMAGEM_VIA_CAMERA)
{
// Caso o usuário tenha tido êxito em tirar uma foto.
if (resultCode == RESULT_OK)
{
// Atualiza a caixa de mensagens.
textViewResultado.setText("Imagem gravada com sucesso");
// Lê a imagem gravada.
File sdcard = Environment.getExternalStorageDirectory();
mImageBitmap=BitmapFactory.decodeFile(sdcard+"/MinhasImagens/" + nomeDoArquivo);
// Gera um thumbnail.
Bitmap imagemRedimensionada=Bitmap.createScaledBitmap(mImageBitmap, 300, 200, false);
// Rotaciona a imagem em 90 graus.
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap imagemRotacionada = Bitmap.createBitmap(imagemRedimensionada , 0, 0, imagemRedimensionada.getWidth(), imagemRedimensionada.getHeight(), matrix, true);
// Mostra o thumbnail da foto na tela do app.
mImageBitmapThumb = imagemRotacionada;
imageViewFoto.setVisibility(View.VISIBLE);
imageViewFoto.setImageBitmap(mImageBitmapThumb);
}
else
{
// Atualiza mensagem de erro.
textViewResultado.setText("Operação cancelada pelo usuário");
// Restaura imagem original (de preview).
int id=getResources().getIdentifier("com.example.fotografo:drawable/preview", null, null);
imageViewFoto.setImageResource(id);
}
}
}
}
Pronto! Basta isso. Execute o projeto. O app vai abrir uma tela inicial com a imagem de preview, aguardando que o usuário pressione o botão "fotografar". Ao fazê-lo, ele será redirecionado para o aplicativo nativo de foto do dispositivo. Depois que a foto for tirada e o usuário clicar em "save" na imagem, o controle será retomado pelo nosso app, que mostrará a foto no lugar da imagem de preview:
Também, utilizando as classes "BitMap" e "Matrix", fizemos uma operação de rotação e outra de redimensionamento da imagem, para que aparecesse em pé na tela do celular e na forma de "thumbnail".
Para quem preferir fazer obter o código-fonte completo, eis aqui o link de download. Se quiser visualizar direto no celular, eis o APK.
Até a próxima e fiquem ligados!
Nenhum comentário:
Postar um comentário