Tutorial Android #22 – Internacionalização (i18n)

Padrão

Olá pessoal! No tutorial de hoje, vamos ver como traduzir nossa aplicação para que ela se torne multi-linguagem. Isso é bastante interessante caso você tenha a intenção de colocar sua aplicação lá no Google Play.

Bom, o grande “segredo” da internacionalização consiste na pasta values do projeto. Nessa pasta, no caso do nosso projeto, temos hoje o arquivo arrays.xml e strings.xml. Esses arquivos irão conter valores correspondentes a cada um dos idiomas que nossa aplicação suportará. Hoje, temos nossa aplicação com o idioma padrão Português. Como o emulador do Android 2.2 não tem o idioma português, vamos deixá-lo como padrão mesmo, e adicionar suporte ao idioma Espanhol. (nota: se você sabe espanhol, releve as sentenças que eu vou mostrar. Foram todas traduzidas com o auxílio do Google Translator. Eu não falo espanhol!)

Para início de conversa, vamos preparar nosso aplicativo para a internacionalização. Modifique o arquivo strings.xml para que contenha os seguintes valores:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br />
&lt;resources&gt;<br />
    &lt;string name=&quot;hello&quot;&gt;Hello World, ListaRestaurantes!&lt;/string&gt;<br />
    &lt;string name=&quot;app_name&quot;&gt;Lista de Restaurantes&lt;/string&gt;<br />
    &lt;string name=&quot;nome&quot;&gt;Nome:&lt;/string&gt;<br />
    &lt;string name=&quot;endereco&quot;&gt;Endereço:&lt;/string&gt;<br />
	&lt;string name=&quot;tipo&quot;&gt;Tipo:&lt;/string&gt;<br />
	&lt;string name=&quot;rodizio&quot;&gt;Rodízio&lt;/string&gt;<br />
	&lt;string name=&quot;fast_food&quot;&gt;Fast Food&lt;/string&gt;<br />
	&lt;string name=&quot;a_domicilio&quot;&gt;A Domicílio&lt;/string&gt;<br />
	&lt;string name=&quot;localizacao&quot;&gt;Localização &lt;/string&gt;<br />
	&lt;string name=&quot;nao_atribuido&quot;&gt;(não atribuída)&lt;/string&gt;<br />
	&lt;string name=&quot;anotacoes&quot;&gt;Anotações&lt;/string&gt;<br />
	&lt;string name=&quot;conta_twitter&quot;&gt;Conta do Twitter&lt;/string&gt;<br />
	&lt;string name=&quot;hora_do_almoco&quot;&gt;Hora do Almoço!&lt;/string&gt;<br />
	&lt;string name=&quot;descartado&quot;&gt;Descartado.&lt;/string&gt;<br />
	&lt;string name=&quot;sem_internet&quot;&gt;Conexão com a Internet indisponível&lt;/string&gt;<br />
	&lt;string name=&quot;local_salvo&quot;&gt;Localização salva&lt;/string&gt;<br />
	&lt;string name=&quot;definir&quot;&gt;Definir&lt;/string&gt;<br />
	&lt;string name=&quot;cancelar&quot;&gt;Cancelar&lt;/string&gt;<br />
	&lt;string name=&quot;notificacao&quot;&gt;Hora do Almoço! Está com fome?&lt;/string&gt;<br />
	&lt;string name=&quot;erro_timeline&quot;&gt;Erro manipulando timeline Twitter&lt;/string&gt;<br />
	&lt;string name=&quot;erro_activity&quot;&gt;Erro enviando dados para a Activity&lt;/string&gt;<br />
	&lt;string name=&quot;timeline_twitter&quot;&gt;Timeline Twitter&lt;/string&gt;<br />
	&lt;string name=&quot;salvar_localizacao&quot;&gt;Salvar Localização&lt;/string&gt;<br />
	&lt;string name=&quot;exibir_mapa&quot;&gt;Exibir Mapa&lt;/string&gt;<br />
	&lt;string name=&quot;adicionar&quot;&gt;Adicionar&lt;/string&gt;<br />
	&lt;string name=&quot;configuracoes&quot;&gt;Configurações&lt;/string&gt;<br />
	&lt;string name=&quot;modo_listagem&quot;&gt;Modo de Listagem&lt;/string&gt;<br />
	&lt;string name=&quot;modo_listagem_desc&quot;&gt;Escolha o modo de listagem a ser utilizado&lt;/string&gt;<br />
	&lt;string name=&quot;modo_listagem_titulo&quot;&gt;Escolha o modo de listagem&lt;/string&gt;<br />
	&lt;string name=&quot;alarme&quot;&gt;Tocar Alarme no Almoço&lt;/string&gt;<br />
	&lt;string name=&quot;alarme_desc&quot;&gt;Marque se deseja ser informado sobre a hora do almoço&lt;/string&gt;<br />
	&lt;string name=&quot;alarme_hora&quot;&gt;Horário do Alarme do Almoço&lt;/string&gt;<br />
	&lt;string name=&quot;alarme_hora_desc&quot;&gt;Configure seu horário desejado para o alarme&lt;/string&gt;<br />
	&lt;string name=&quot;notificacao_titulo&quot;&gt;Ativar Notificação&lt;/string&gt;<br />
	&lt;string name=&quot;notificacao_desc&quot;&gt;Marque caso deseje um ícone na barra de status, ou desmarque para a notificação em tela cheia&lt;/string&gt;<br />
&lt;/resources&gt;

Basicamente, definimos alguns alias para as strings do nosso aplicativo. Porém, em alguns trechos do código, ainda temos strings como constantes de texto. Para isso, vamos alterá-los para utilizar os resources deste arquivo. Primeiramente, nos formulários e menus em XML, vamos alterar os arquivos form_detalhes.xml, tanto na pasta layout

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br />
&lt;TableLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;<br />
    android:layout_width=&quot;fill_parent&quot;<br />
    android:layout_height=&quot;wrap_content&quot;<br />
    android:stretchColumns=&quot;1&quot; &gt;<br />
    &lt;TableRow&gt;<br />
        &lt;TextView android:text=&quot;@string/nome&quot;/&gt;<br />
        &lt;EditText android:id=&quot;@+id/nome&quot;/&gt;<br />
    &lt;/TableRow&gt;<br />
    &lt;TableRow&gt;<br />
    	&lt;TextView android:text=&quot;@string/endereco&quot;/&gt;<br />
    	&lt;EditText android:id=&quot;@+id/end&quot;/&gt;<br />
    &lt;/TableRow&gt;<br />
    &lt;TableRow&gt;<br />
    	&lt;TextView android:text=&quot;@string/tipo&quot;/&gt;<br />
    	&lt;RadioGroup android:id=&quot;@+id/tipos&quot;&gt;<br />
    		&lt;RadioButton android:id=&quot;@+id/rodizio&quot;<br />
       			android:text=&quot;@string/rodizio&quot;/&gt;<br />
    		&lt;RadioButton android:id=&quot;@+id/fast_food&quot;<br />
        		android:text=&quot;@string/fast_food&quot;/&gt;<br />
        	&lt;RadioButton android:id=&quot;@+id/a_domicilio&quot;<br />
            	android:text=&quot;@string/a_domicilio&quot;/&gt;<br />
   		&lt;/RadioGroup&gt;<br />
	&lt;/TableRow&gt;<br />
	&lt;TableRow&gt;<br />
	    &lt;TextView android:text=&quot;@string/localizacao&quot; /&gt;<br />
	    &lt;TextView android:id=&quot;@+id/localizacao&quot; android:text=&quot;@string/nao_atribuido&quot; /&gt;<br />
	&lt;/TableRow&gt;<br />
    &lt;EditText android:id=&quot;@+id/anotacoes&quot;<br />
    	android:singleLine=&quot;false&quot;<br />
    	android:gravity=&quot;top&quot;<br />
    	android:lines=&quot;2&quot;<br />
    	android:scrollHorizontally=&quot;false&quot;<br />
    	android:maxLines=&quot;2&quot;<br />
    	android:maxWidth=&quot;200sp&quot;<br />
    	android:hint=&quot;@string/anotacoes&quot;<br />
    	android:layout_marginTop=&quot;4dip&quot;/&gt;<br />
    &lt;EditText android:id=&quot;@+id/twitter&quot;<br />
        android:hint=&quot;@string/conta_twitter&quot; /&gt;<br />
&lt;/TableLayout&gt;

… quanto na pasta layout-land

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br />
&lt;TableLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;<br />
    android:layout_width=&quot;fill_parent&quot;<br />
    android:layout_height=&quot;wrap_content&quot;<br />
    android:stretchColumns=&quot;2&quot; &gt;<br />
    &lt;TableRow&gt;<br />
        &lt;TextView android:text=&quot;@string/nome&quot;/&gt;<br />
        &lt;EditText android:id=&quot;@+id/nome&quot;<br />
            android:layout_span=&quot;2&quot; /&gt;<br />
    &lt;/TableRow&gt;<br />
    &lt;TableRow&gt;<br />
    	&lt;TextView android:text=&quot;@string/endereco&quot;/&gt;<br />
    	&lt;EditText android:id=&quot;@+id/end&quot;<br />
    	    android:layout_span=&quot;2&quot; /&gt;<br />
    &lt;/TableRow&gt;<br />
    &lt;TableRow&gt;<br />
    	&lt;TextView android:text=&quot;@string/tipo&quot;/&gt;<br />
    	&lt;RadioGroup android:id=&quot;@+id/tipos&quot;&gt;<br />
    		&lt;RadioButton android:id=&quot;@+id/rodizio&quot;<br />
       			android:text=&quot;@string/rodizio&quot;/&gt;<br />
    		&lt;RadioButton android:id=&quot;@+id/fast_food&quot;<br />
        		android:text=&quot;@string/fast_food&quot;/&gt;<br />
        	&lt;RadioButton android:id=&quot;@+id/a_domicilio&quot;<br />
            	android:text=&quot;@string/a_domicilio&quot;/&gt;<br />
   		&lt;/RadioGroup&gt;<br />
   		&lt;LinearLayout<br />
   		    android:layout_width=&quot;fill_parent&quot;<br />
   		    android:layout_height=&quot;fill_parent&quot;<br />
   		    android:orientation=&quot;vertical&quot;&gt;<br />
   		    &lt;EditText android:id=&quot;@+id/anotacoes&quot;<br />
    			android:singleLine=&quot;false&quot;<br />
	    		android:gravity=&quot;top&quot;<br />
    			android:lines=&quot;4&quot;<br />
    			android:scrollHorizontally=&quot;false&quot;<br />
    			android:maxLines=&quot;4&quot;<br />
    			android:maxWidth=&quot;140sp&quot;<br />
    			android:layout_width=&quot;fill_parent&quot;<br />
    			android:layout_height=&quot;wrap_content&quot;<br />
    			android:hint=&quot;@string/anotacoes&quot; /&gt;<br />
   		    &lt;EditText android:id=&quot;@+id/twitter&quot;<br />
   		        android:layout_width=&quot;fill_parent&quot;<br />
   		        android:layout_height=&quot;wrap_content&quot;<br />
   		        android:hint=&quot;@string/conta_twitter&quot;/&gt;<br />
   		    &lt;LinearLayout<br />
   		        android:layout_width=&quot;wrap_content&quot;<br />
   		        android:layout_height=&quot;wrap_content&quot;<br />
   		        android:orientation=&quot;horizontal&quot;&gt;<br />
   		        &lt;TextView android:text=&quot;@string/localizacao&quot;<br />
   		            android:layout_width=&quot;wrap_content&quot;<br />
   		            android:layout_height=&quot;wrap_content&quot;/&gt;<br />
   		        &lt;TextView android:id=&quot;@+id/localizacao&quot;<br />
   		            android:text=&quot;@string/nao_atribuido&quot;<br />
   		            android:layout_width=&quot;wrap_content&quot;<br />
   		            android:layout_height=&quot;wrap_content&quot;/&gt;<br />
   		    &lt;/LinearLayout&gt;<br />
   		&lt;/LinearLayout&gt;<br />
	&lt;/TableRow&gt;<br />
&lt;/TableLayout&gt;

… além dos arquivos opcao.xml

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br />
&lt;menu xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;<br />
	&lt;item android:id=&quot;@+id/adicionar&quot;<br />
	    android:title=&quot;@string/adicionar&quot;<br />
	    android:icon=&quot;@drawable/adicionar&quot;/&gt;<br />
	&lt;item android:id=&quot;@+id/prefs&quot;<br />
	    android:title=&quot;@string/configuracoes&quot;<br />
	    android:icon=&quot;@drawable/menu_preferencias&quot;/&gt;<br />
&lt;/menu&gt;

e opcao_detalhes.xml, da pasta menu

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br />
&lt;menu xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot; &gt;<br />
	&lt;item android:id=&quot;@+id/twitter&quot;<br />
	    android:title=&quot;@string/timeline_twitter&quot;<br />
	    android:icon=&quot;@drawable/twitter&quot;/&gt;<br />
	&lt;item android:id=&quot;@+id/localizacao&quot;<br />
	    android:title=&quot;@string/salvar_localizacao&quot;<br />
	    android:icon=&quot;@drawable/gps&quot;/&gt;<br />
	&lt;item android:id=&quot;@+id/mapa&quot;<br />
	    android:title=&quot;@string/exibir_mapa&quot;<br />
	    android:icon=&quot;@drawable/mapa&quot;/&gt;<br />
&lt;/menu&gt;

Nas nossas classes, também temos alguns trechos que precisam ser adaptados. Primeiramente na classe FormularioDetalhes

Toast.makeText(FormularioDetalhes.this, getString(R.string.descartado), Toast.LENGTH_SHORT);

Toast.makeText(this, getString(R.string.sem_internet), Toast.LENGTH_LONG).show();

Toast.makeText(FormularioDetalhes.this, getString(R.string.local_salvo), Toast.LENGTH_LONG);

… na classe PreferenciaHorario

setPositiveButtonText(getContext().getString(R.string.definir));<br />
setNegativeButtonText(getContext().getString(R.string.cancelar));

… na classe ReceptorAlarme

Notification nota = new Notification(R.drawable.notificacao, context.getString(R.string.hora_do_almoco), System.currentTimeMillis());

nota.setLatestEventInfo(context, context.getString(R.string.app_name), context.getString(R.string.notificacao), i);

… e na classe TwitterService

Log.e(getString(R.string.app_name), getString(R.string.erro_timeline), ex);

Log.w(getString(R.string.app_name), getString(R.string.erro_activity), ex);

Caso a aplicação seja executada agora, ela deve rodar normalmente como rodava antes. Agora, vamos criar os arquivos relativos ao novo idioma. Crie um novo diretório no projeto chamado values-es na pasta res. Dentro dele, teremos 2 arquivos XML, arrays.xml

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br />
&lt;resources&gt;<br />
	&lt;string-array name=&quot;nomes_ordenacao&quot;&gt;<br />
	    &lt;item&gt;Por Nombre, Ascendente&lt;/item&gt;<br />
	    &lt;item&gt;Por Nombre, Descendente&lt;/item&gt;<br />
	    &lt;item&gt;Por Tipo&lt;/item&gt;<br />
	    &lt;item&gt;Por Dirección, Ascendente&lt;/item&gt;<br />
	    &lt;item&gt;Por Dirección, Descendente&lt;/item&gt;<br />
	&lt;/string-array&gt;<br />
	&lt;string-array name=&quot;opcoes_ordenacao&quot;&gt;<br />
	    &lt;item&gt;nome ASC&lt;/item&gt;<br />
	    &lt;item&gt;nome DESC&lt;/item&gt;<br />
	    &lt;item&gt;tipo, nome ASC&lt;/item&gt;<br />
	    &lt;item&gt;endereco ASC&lt;/item&gt;<br />
	    &lt;item&gt;endereco DESC&lt;/item&gt;<br />
	&lt;/string-array&gt;<br />
&lt;/resources&gt;

e strings.xml

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br />
&lt;resources&gt;<br />
    &lt;string name=&quot;hello&quot;&gt;Hello World, ListaRestaurantes!&lt;/string&gt;<br />
    &lt;string name=&quot;app_name&quot;&gt;Lista de Restaurantes&lt;/string&gt;<br />
    &lt;string name=&quot;nome&quot;&gt;Nombre:&lt;/string&gt;<br />
    &lt;string name=&quot;endereco&quot;&gt;Dirección:&lt;/string&gt;<br />
	&lt;string name=&quot;tipo&quot;&gt;Tipo:&lt;/string&gt;<br />
	&lt;string name=&quot;rodizio&quot;&gt;Rotación&lt;/string&gt;<br />
	&lt;string name=&quot;fast_food&quot;&gt;Comida Rápida&lt;/string&gt;<br />
	&lt;string name=&quot;a_domicilio&quot;&gt;Ubicación&lt;/string&gt;<br />
	&lt;string name=&quot;localizacao&quot;&gt;Posición &lt;/string&gt;<br />
	&lt;string name=&quot;nao_atribuido&quot;&gt;(sin asignar)&lt;/string&gt;<br />
	&lt;string name=&quot;anotacoes&quot;&gt;Anotaciones&lt;/string&gt;<br />
	&lt;string name=&quot;conta_twitter&quot;&gt;Cuenta de Twitter&lt;/string&gt;<br />
	&lt;string name=&quot;hora_do_almoco&quot;&gt;La Hora del Almuerzo!&lt;/string&gt;<br />
	&lt;string name=&quot;descartado&quot;&gt;Tirado.&lt;/string&gt;<br />
	&lt;string name=&quot;sem_internet&quot;&gt;Conexión com la Internet no está disponible&lt;/string&gt;<br />
	&lt;string name=&quot;local_salvo&quot;&gt;Posición salva&lt;/string&gt;<br />
	&lt;string name=&quot;definir&quot;&gt;Definir&lt;/string&gt;<br />
	&lt;string name=&quot;cancelar&quot;&gt;Cancelar&lt;/string&gt;<br />
	&lt;string name=&quot;notificacao&quot;&gt;La Hora del Almuerzo! ¿Tienes hambre?&lt;/string&gt;<br />
	&lt;string name=&quot;erro_timeline&quot;&gt;Error de Línea de Tiempo de Twitter&lt;/string&gt;<br />
	&lt;string name=&quot;erro_activity&quot;&gt;Erros al enviar datos a la Activity&lt;/string&gt;<br />
	&lt;string name=&quot;timeline_twitter&quot;&gt;Línea de Tiempo de Twitter&lt;/string&gt;<br />
	&lt;string name=&quot;salvar_localizacao&quot;&gt;Guardar Posición&lt;/string&gt;<br />
	&lt;string name=&quot;exibir_mapa&quot;&gt;Ver Mapa&lt;/string&gt;<br />
	&lt;string name=&quot;adicionar&quot;&gt;Añadir&lt;/string&gt;<br />
	&lt;string name=&quot;configuracoes&quot;&gt;Ajustes&lt;/string&gt;<br />
	&lt;string name=&quot;modo_listagem&quot;&gt;Modo de Lista&lt;/string&gt;<br />
	&lt;string name=&quot;modo_listagem_desc&quot;&gt;Elija el modo de lista que se utiliza&lt;/string&gt;<br />
	&lt;string name=&quot;modo_listagem_titulo&quot;&gt;Elija el modo de lista&lt;/string&gt;<br />
	&lt;string name=&quot;alarme&quot;&gt;Reproducir Alarma en el Almuerzo&lt;/string&gt;<br />
	&lt;string name=&quot;alarme_desc&quot;&gt;Selecciona se desea recibir información sobre la hora del almuerzo&lt;/string&gt;<br />
	&lt;string name=&quot;alarme_hora&quot;&gt;La Hora del Almuerzo&lt;/string&gt;<br />
	&lt;string name=&quot;alarme_hora_desc&quot;&gt;Ajuste el tiempo deseado para el alarma&lt;/string&gt;<br />
	&lt;string name=&quot;notificacao_titulo&quot;&gt;Habilitar Notificación&lt;/string&gt;<br />
	&lt;string name=&quot;notificacao_desc&quot;&gt;Seleccione si desea un icono en la barra de estado o borrar la notificación en pantalla completa&lt;/string&gt;<br />
&lt;/resources&gt;

E pronto! Para ver seu aplicativo no idioma espanhol, siga até o menu principal, Settings -> Language & keyboard -> Select language e selecione Español.

Como de costume, pra baixar o aplicativo, basta clicar aqui.

Até a próxima!