quinta-feira, 25 de novembro de 2010

Defesa do Mestrado

Olá povo,

Depois de mais de 1 ano e 8 meses, quarta-feira (24/11/2010) eu defendi meu mestrado. O trabalho tinha como tema iOS2Droid - Uma ferramenta de tradução de aplicações iPhone para Android e teve orientação do professor Silvio Meira e co-orientação do professor left. A banca examinadora foi composta pelos Professores Carlos Ferraz e Felipe Furtado.

Tô colocando esse post, para que depois de tanto trabalho e esforço, eu possa lembrar como foi legal não só esse dia, mas o curso como um todo.


Fábrica Sofistic
No mestrado profissional do CESAR.edu os assuntos das disciplinas cursadas são aplicadas em um problema real de um cliente, que a fábrica de software (formada pelos próprios alunos que são divididos em grupos) deve solucionar.
A divisão dos grupos é feita pelo próprio pessoal do CESAR.edu, e infelizmente fiquei em uma fábrica na qual não me identifiquei com o problema a ser resolvido. Mas graças a Deus, tive a iniciativa de pedir pra mudar de fábrica, e fui aceito pela Sofistic. ValeuVivi, Alessandra, Jonas e Enderson!



Enderson


Alessandra


Jonas


Viviane


Banca de Negócios (depois, óbvio...)
Após pagar (quase) todas as disciplinas, temos que defender o produtos desenvolvido durante o curso para uma banca formada por especialistas em negócios.






Quando você termina de cursar todas as disciplinas, você pensa: "Ótimo! Agora é SÓ escrever a dissertação. Vai ser tranquilo". Amarga ilusão. Mas o dia chega...

O dia da defesa...

Comentário no Twitter (teve mais dois ou três :)


Dissertação pronta e impressa (pra apresentação)


Antes da apresentação...


Reconhecimento não tem preço. Valeu Felipe!

Agradeço a todos que me ajudaram (e que me aguentaram) direta ou indiretamente nessa caminhada. Ela ainda não terminou, pois preciso fazer as alterações solicitadas pela banca, mas com certeza, me sinto bem mais leve agora.

Quem quiser dar uma conferida na dissertação, é só clicar aqui.

4br4ç05,
nglauber

segunda-feira, 22 de novembro de 2010

TabHost, TabWidget e TabActivity

Olá povo,

Dar aulas é um desafio bem grande, e às vezes você paga uns micos esquecendo coisas simples. Esse post é dedicado aos meus alunos da LinuxFI em João Pessoa, aos quais presenciaram mais um mico proporcionado por minha pessoa.
Estava explicando como se fazia para criar uma tela com abas (ou guias, como preferir) no Android, e como não queria fazer como estava no livro, fui fazer de outro jeito. Aí claro que deu merda. Então implementei de outro jeito e prometi que iria fazer esse post. No final acabou que um aluno (perdão por não lembrar do nome) Raniere Fernandes descobriu o que estava faltando (era um maldito tabHost.setup()), mas aí já era!

Então vamos lá! Vou mostrar primeiro a maneira mais simples. Primeiro vou criar dois arquivos de layout: aba1.xml e aba2.xml.


<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/raizAba1">

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Nome:" />
<EditText
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:id="@+id/edtNome"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email"/>
<EditText
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:id="@+id/edtEmail"/>
</LinearLayout>


<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/raizAba2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Observações:"/>
<EditText
android:id="@+id/edtObs"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:gravity="top"/>
</LinearLayout>

Notem que o elemento raiz do XML tem os identificadores raizAba1 e raizAba2. Esses identificadores serão utilizados para setar o conteúdo das abas.
Vamos agora ao código que configura a tela.

public class ExTabActivity1 extends TabActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

TabHost tabHost = getTabHost();

LayoutInflater.from(this).inflate(
R.layout.aba1, tabHost.getTabContentView());

LayoutInflater.from(this).inflate(
R.layout.aba2, tabHost.getTabContentView());

TabSpec aba1 = tabHost.newTabSpec("foo1");
aba1.setIndicator("Informações");

aba1.setContent(R.id.raizAba1);

TabSpec aba2 = tabHost.newTabSpec("foo2");
aba2.setIndicator("Observações");
aba2.setContent(R.id.raizAba2);

tabHost.addTab(aba1);
tabHost.addTab(aba2);
}
}

A classe TabActivity da qual nossa classe está herdando facilita o nosso trabalho para telas que usam abas. No método onCreate estamos obtendo a instância do TabHost que é o gerenciador de layout responsável por esse tipo de tela. Internamente ele contém um objeto TabWidget e um FrameLayout que exibe o conteúdo das abas (como veremos no próximo exemplo).

Cada aba é representada por um objeto do tipo TabSpec, que é adicionado ao TabHost. Para criar uma TabSpec chamamos o método newTabSpec do objeto TabHost passando uma tag de identificação. Para definir o texto de cada aba chamamos o método setIndicator. E para setar o conteúdo, carregamos o arquivo de layout através da chamada:

LayoutInflater.from(this).inflate(
R.layout.aba1, tabHost.getTabContentView());

Isso carregará o arquivo de layout no FrameLayout interno do TabHost. Uma vez que o layout está carregado, podemos definir o conteúdo da TabSpec, chamando o método setContent e passando o id da view raiz do arquivo de layout. No caso, R.id.raizAba1 para primeira aba e R.id.raizAba2 para a segunda.

Mas e se eu quiser ter mais do que uma TabHost na minha tela? Como, por exemplo, um botão no canto inferior? Pois é, esse era o exemplo que eu queria ter terminado em "Jampa".
Primeiro devemos criar um arquivo de layout igual ao definido abaixo, e a este, chamaremos de meuTabHost.xml:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">

<TabHost
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/meuTabHost"
android:layout_weight="1">
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>

<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@android:id/tabcontent"/>
</LinearLayout>
</TabHost>

<Button
android:text="Salvar"
android:id="@+id/Button01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>


Notem que nele, dentro de um LinearLayout, temos um TabHost, que dentro dele temos um TabWidget e um FrameLayout, conforme já tínhamos descrito. Uma atenção especial nos ids do TabHost e do TabWidget, que devem, obrigatoriamente chamar-se @android:id/tabs e @android:id/tabcontent respectivamente.

Para finalizar, a classe Java ficaria conforme abaixo:


public class ExTabActivity2 extends Activity {

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.meutab);

TabHost tabHost = (TabHost)findViewById(
R.id.meuTabHost);

tabHost.setup();

// O resto é igual ao exemplo anterior
}
}


Agora a nossa classe herda de Activity e não mais de TabActivity. Dessa forma, temos que chamar o método setContentView passando o nosso layout e chamar o (MALDITO) método setup do objeto TabHost, que agora é obtido através do arquivo de layout.

Aê turma da LinuxFI, um "Aleluia" pro professor! :)

4br4ç05,
nglauber

sexta-feira, 19 de novembro de 2010

Android ou iPhone? Que tal os dois?

Olá povo,

Na próxima quarta-feira 24/11 estarei defendendo minha dissertação de mestrado. Meu tema trata de como fazer com que uma aplicação iPhone execute na plataforma Android. Para isso, desenvolvi uma ferramenta chamada iOS2Droid, que converte o código fonte escrito em Objective-C (linguagem do iPhone) para Java (usado no Android). Essa ferramenta se torna muito útil principalmente para empresas de desenvolvimento que já criam aplicações para iPhone e querem converter as mesmas para a plataforma do Google.

Então uma das seções que apresentarei na minha defesa, são os concorrentes do iOS2Droid, que vou listar pra vocês abaixo:


XMLVM (http://www.xmlvm.org) é um trabalho realizado por Arno Puder que realiza a conversão de arquivos de linguagem intermediária (como os .class do Java) para um arquivo XML, que por sua vez pode ser convertido para outra linguagem.
Um dos recursos do XMLVM é a possibilidade de converter aplicações Android para iPhone. Exatamente o oposto do que é proposto pelo iOS2Droid. Um detalhe é que a aplicação desenvolvida em Android, utiliza o framework do iPhone escrito em Java.

Dessa forma, um diferencial do iOS2Droid é que a aplicação desenvolvida em iPhone utiliza o framework nativo, e a ferramenta faz as adaptações para converte-la em uma aplicação Android.


O PhoneGap (http://www.phonegap.com/) é um framework de desenvolvimento open source para construir aplicações mobile cross-platform. As aplicações são construídas utilizando HTML e JavaScript e permite que uma aplicação possa executar em diversas plataformas além de Android e iPhone, como Palm, Symbian e Blackberry.


O Titanium Mobile (http://www.appcelerator.com/products/titanium-mobile-application-development/) faz trabalho similar ao PhoneGap. O desenvolvedor cria as aplicações utilizando HTML/JavaScript/CSS e a mesma poderá ser executada em telefones Android ou no iPhone.
A ferramenta tem uma versão gratuita com funcionalidade reduzida e uma paga (com todas as funcionalidades obviamente).

Um ponto positivo do iOS2Droid em relação a essas duas ferramentas, é que o desenvolvedor não tem que aprender um novo framework de desenvolvimento.


Com o Adobe Air (http://www.adobe.com/br/products/air/) os desenvolvedores podem criar aplicações com o Flash CS5 para dispositivos móveis como: iPhone, Android e BlackBerry. Assim como outras ferramentas já citadas, pode-se utilizar HTML+CSS+JavaScript, porém o desenvolvedor pode contar também com a linguagem ActionScprit.


Para finalizar, temos o Elips Studio (http://www.openplug.com/products/elips-studio) que é um SDK baseado no Adobe Flex, onde o desenvolvedor cria suas aplicações usando ActionScript e MXML, e as aplicações serão disponibilizadas para Android e iPhone através de uma engine que converte esse código em uma aplicação nativa.

Podemos notar que todos os concorrentes apresentados aqui se baseiam em novas aplicações. E todas aquelas aplicações disponíveis na AppStore? O iOS2Droid pensou nelas! A ferramenta converte um código existente em uma aplicação Android. E os desenvolvedores de aplicações para iPhone poderão continuar utilzando o seu bom e velho Xcode. Podendo agora, ver suas aplicações executando em dispositivos Android com pouquíssimo trabalho.

Espero que a banca goste do trabalho. E vocês o que acham da idéia? Quem quiser dar uma conferida na dissertação é só clicar aqui.

4br4ç05,
nglauber

quarta-feira, 3 de novembro de 2010

Hello World Samsung bada

Olá povo,

Pra quem pensa que nesse blog só sai artigo sobre Android... Vocês tem uma grande parcela de razão :) Então hoje vou variar um pouquinho e falar sobre a plataforma bada da Samsung. Depois faremos um "Hello World"!

bada é o sistema operacional desenvolvido pela Samsung projetado para cobrir tanto os celulares "top de linha" quanto celulares mais modestos da compania. A empresa afirma que bada irá rapidamente substituir sua plataforma proprietária para "feature phones", transformando esse tipo de aparelho em smartphones.

Para iniciar o desenvolvimento com a plataforma devemos acessar http://developer.bada.com, se registrar gratuitamente e fazer o download do SDK. O instalador do SDK é bem simples, e o bacana é que diferentemente do Android, não precisamos baixar o Eclipse, baixar SDK, instalar plugin... Tudo é instalado e configurado junto.

A IDE é baseada em Eclipse e é uma extensão do CDT que permite o desenvolvimento C/C++ . Dentro da IDE temos compilador, debugger e a visualização da aplicação através de um simulador.

Vamos criar o primeiro projeto. Acesse o menu File > New > bada Application Project, digite "HelloWorld" no nome do projeto, selecione "bada Form Based Application", e clique em "Finish" (existem diversas configurações se clicar em Next, mas vou deixar pra um próximo post). Será criada a seguinte estrutura do projeto:


  • Include: bibliotecas do bada;
  • inc: ficarão os arquivos de cabeçalho (extensão .h);
  • src: arquivos de implementação (extensão .cpp);
  • Home: arquivos de escrita e leitura utilizados pela aplicação;
  • Res: Arquivos de recursos.
Abra o arquivo IDF_FORM1.xml. Ele terá um botão com o texto "OK". Arraste um componente "Edit Field" logo acima do botão e um "Label" abaixo.
Agora, abra o arquivo Form1.h e deixe a seção "protected" como abaixo:


// Implementation
protected:
static const int ID_BUTTON_OK = 101;
Osp::Ui::Controls::Button *__pButtonOk;
Osp::Ui::Controls::Label *__meuLabel;
Osp::Ui::Controls::EditField *__meuEdit;


No arquivo Form1.cpp, fica a implementação do comportamento da classe. No método OnInitializing, vamos realizar a ligação entre o código-fonte e os componentes que adicionamos ao formulário. Deixe-o conforme abaixo:


result
Form1::OnInitializing(void)
{
result r = E_SUCCESS;

// TODO: Add your initialization code here

// Get a button via resource ID
__pButtonOk = static_cast<Button *>
(GetControl(L"IDC_BUTTON_OK"));
__meuLabel = static_cast<Label *>
(GetControl(L"IDC_LABEL1"));
__meuEdit = static_cast<EditField *>
(GetControl(L"IDC_EDITFIELD1"));

if (__pButtonOk != null)
{
__pButtonOk->SetActionId(ID_BUTTON_OK);
__pButtonOk->AddActionEventListener(*this);
}
return r;
}


Notem que inicializamos os componentes com o método GetControl passando uma String. Essa String representa o ID do componente. Depois, associamos um evento ao botão, que é tratado pela própria classe pelo método OnActionPerformed. Deixe-o conforme abaixo:


void
Form1::OnActionPerformed(const Osp::Ui::Control& source, int actionId)
{
switch(actionId)
{
case ID_BUTTON_OK:
{
AppLog("OK Button is clicked! \n");

__meuLabel->SetText(
__meuEdit->GetText().GetPointer());

__meuLabel->RequestRedraw(true);
}
break;
default:
break;
}
}


A maioria do código já foi implementado pelo plugin, o que fizemos aqui foi definir o texto do label de acordo com o que o usuário digitou na caixa de texto e logo após, solicitar o redesenho do componente. Feito isso, clique com o botão direito sobre o projeto e selecione "Run as > bada Simulator Application". A aplicação deve ficar como na figura abaixo:


Estou começando a aprender essa nova plataforma. Mais informações aqui. O que acharam? Deixem seus comentários.

4br4ç05,
nglauber