quarta-feira, 25 de maio de 2011

Android: Reconhecimento de voz

Olá povo,

Estou corrigindo os trabalhos do pessoal do TECDAM e uma funcionalidade simples do Android que foi utilizada pelo aluno Leonardo Melo me chamou a atenção: o reconhecimento de voz. Essa API foi introduzida na versão 2.1 do Android, e apesar de simples, ela é pouco explorada (por mim inclusive). Para utiliza-la basta é bem simples. Basta chamar a atividade que iniciará o reconhecimento do que será falado, e em seguida obter lista dos textos que foram reconhecidos através do retorno dessa atividade.

Antes de iniciar, precisamos checar se o aparelho suporta essa funcionalidade. Podemos fazer isso através do código abaixo:


PackageManager pm = getPackageManager();
Intent it = new Intent(
RecognizerIntent.ACTION_RECOGNIZE_SPEECH)

List<ResolveInfo> activities =
pm.queryIntentActivities(it, 0);

if (activities.size() != 0) {
// Aparelho suporta Reconhecimento de Voz
} else {
// Aparelho NÃO suporta Reconhecimento de Voz
}

Com o PackageManager podemos obter uma lista de informações sobre Activities baseado em uma Intent. O método queryIntentActivities retorna a lista de atividades que respondem por uma determinada ação. No nosso caso, procuramos pela ação ACTION_RECOGNIZE_SPEECH, se alguma Activity responder por essa ação, é porque o aparelho tem suporte ao reconhecimento de voz.

Para iniciar o reconhecimento de voz, basta usar o código abaixo:


Intent intent = new Intent(
RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);

intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
"Fala alguma coisa!");

startActivityForResult(intent, MEU_REQUEST_CODE);


Isso resultará na imagem abaixo:



Após capturar a voz, ele fará o reconhecimento e enviará os resultados como resultado da Activity. Para tratar o resultado, usamos o método onActivityResult da atividade que chamou o reconhecimento de voz, conforme abaixo:


protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (requestCode == MEU_REQUEST_CODE
&& resultCode == RESULT_OK) {

// Contém a lista com os resultados
ArrayList<String> matches =
data.getStringArrayListExtra(
RecognizerIntent.EXTRA_RESULTS);
}
}


Mais informações aqui.

4br4ç0s,
nglauber

segunda-feira, 23 de maio de 2011

Curso de Android em João Pessoa

Olá povo,

A LinuxFI abriu as inscrições para a segunda turma de Google Android. As aulas acontecerão aos sábados e domingos durante 3 finais de semana.

No curso, estudaremos os principais recursos da plataforma para smartphones e tablets da Google. Conceitos como Activities, Broadcast Receivers, Handlers, ContentProviders e Services serão aplicados na prática. Veremos também como armazenar informações no banco de dados do celular com SQLite, comunicação com WebServices e com o GoogleMaps, envio de SMS e muito mais.

Quem tiver interesse, pode entrar na página do curso para obter mais informações e fazer sua inscrição.



4br4ç05,
nglauber

terça-feira, 10 de maio de 2011

Screenshot de dispositivo Android via app Java

Olá povo,

Todos devem saber que é possível tirar um screenshot da tela de um aparelho Android através da perspectiva DDMS do Eclipse. Uma outra alternativa é executar a aplicação DDMS a partir do diretório tools do Android SDK. Entretanto, hoje no trabalho eu precisei obter um screenshot de um dispositivo Android programaticamente, ou seja, via código, e exibir essa imagem na tela.

Para fazer isso, podemos utilizar as bibliotecas do DDMS que estão no diretório tools/lib do SDK do Android. Para tirar um screenshot da tela do aparelho utilizaremos o arquivo ddmlib.jar. Copie esse arquivo para o seu projeto e adicione-o ao classpath.

A primeira coisa que devemos fazer é criar uma classe que implemente IDeviceChangeListener, e implementar 3 métodos: deviceChanged(IDevice device, int what), deviceConnected(IDevice device) e deviceDisconnected(IDevice device).
No método deviceConnected devemos guardar a referência de IDevice, é com ela que obteremos o screenshot da tela. Mas antes devemos registrar a classe para capturar a imagem da tela que será capturada.

AndroidDebugBridge.init(false);
AndroidDebugBridge.createBridge();
AndroidDebugBridge.addDeviceChangeListener(
instancia_de_IDeviceChangeListener);

No meu caso, estou usando uma tela SWT. Para tirar um screenshot e carregar na tela, utilizei o código abaixo:

RawImage raw;
try {
raw = device.getScreenshot();
PaletteData pal = new PaletteData(
0xFF00, 0xFF0000, 0xFF000000);
ImageData image = new ImageData(
raw.width, raw.height, raw.bpp,
pal, 1, raw.data);

ImageLoader loader = new ImageLoader();
loader.data = new ImageData[] { image };
loader.save("imagem.png", SWT.IMAGE_PNG);

lblImagem.setImage(new Image(
Display.getCurrent(), "imagem.png"));

} catch (TimeoutException e) {
e.printStackTrace();
} catch (AdbCommandRejectedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}


O resultado pode ser observado abaixo:


Referência:
http://blog.codetastrophe.com/2008/12/using-androiddebugbridge-api-to-get.html

4br4ç05,
nglauber

domingo, 1 de maio de 2011

Conexão 3G no Android

Olá povo,

Meu aluno Rafael Cavalcanti me perguntou como saber o tipo de conexão (Wi-Fi ou 3G) que o aparelho Android está utilizando. O código é bem simples, basta utilizar a classe ConnectivityManager que é um serviço do sistema que provê informações sobre as conexões do aparelho.


ConnectivityManager connec = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);

android.net.NetworkInfo wifi =
connec.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
android.net.NetworkInfo mobile =
connec.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

String s = "Conexão: ";
if (wifi.isConnected()) {
s += "Wi-Fi";
} else if (mobile.isConnected()) {
s += "3G";
} else {
s += "Nenhuma";
}
Toast.makeText(this, s, Toast.LENGTH_LONG).show();
Adicione a permissão android.permission.ACCESS_NETWORK_STATE no seu arquivo AndroidManifest.xml conforme abaixo.

<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"/>

Outra pergunta de Rafael foi como desabilitar, via código, a conexão 3G. Para conseguir isso, dei uma investigada no código fonte do projeto ApnDroid. E fiz um pequeno exemplo QUE USA O CÓDIGO DESSA FERRAMENTA. Para baixa-lo, clique aqui.

4br4ç05,
nglauber