Reflexão de imagens em Java ME

20 dezembro 2009 0 comentários
Este post mostra como criar um efeito de reflexão a partir de uma simples imagem.

Através do método createReflectedImage, da Classe que será mostrada abaixo, podemos fazer a reflexão da imagem passando 3 argumentos:

- A imagem original a ser refletida
- A cor de fundo (usado para imagens transparentes)
- A altura do efeito de reflexão


É necessário criar uma imagem mutável que irá realizar o efeito resultante:

int w = image.getWidth();

int h = image.getHeight();

Image reflectedImage = Image.createImage(w, h + reflectionHeight);

Foi armazenado a largura e altura da imagem original em 2 variáveis int, e em seguida, criou-se a imagem mutável com a mesma largura, mas com uma altura igual a h (imagem original) mais a altura da reflexão especificada.

Para fazer a cópia da imagem original é necessário usar o objeto Graphics da imagem mutável, preenchendo a imagem com a cor de fundo. Então é possível desenhar a imagem original na parte superior fazendo a mutação da imagem.

Para criar o efeito de reflexão em cada linha horizontal da parte da imagem refletida, toma-se a coordenada vertical correspondente da imagem original, então obtem-se os dados RGBA da linha horizontal correspondente à imagem original para calcular o alfa a ser aplicado a esta linha, e então aplicá-lo a cada elemento da matriz de dados RGB para elaborar os dados RGB da imagem refletida, utilizando seu objeto Graphics. Veja:

int[] rgba = new int[w];
int currentY = -1;

for(int i = 0; i < reflectionHeight; i++)
{
int y = (h - 1) - (i * h / reflectionHeight);

if(y != currentY)
image.getRGB(rgba, 0, w, 0, y, w, 1);

int alpha = 0xff - (i * 0xff / reflectionHeight);

for(int j = 0; j < w; j++)
{
int origAlpha = (rgba[j] >> 24);
int newAlpha = (alpha & origAlpha) * alpha / 0xff;

rgba[j] = (rgba[j] & 0x00ffffff);
rgba[j] = (rgba[j] | (newAlpha << 24));
}

g.drawRGB(rgba, 0, w, 0, h + i, w, 1, true);
}
Obs: O array rgba [] contém a linha atual dos dados de pixel, e será atualizada somente quando necessário. Desta forma a imagem é mutada no decorrer da coordenada y. Para usar o método basta criar a imagem original a ser refletida e chamar ReflectedImage.create(x, y, z), passando a imagem original como argumento, juntamente com a cor de fundo e a altura do efeito de reflexão. ReflectedImage.java
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

public class ReflectedImage
{
public static Image create(Image image, int bgColor, int reflectionHeight)
{
int w = image.getWidth();
int h = image.getHeight();

Image reflectedImage = Image.createImage(w, h + reflectionHeight);

Graphics g = reflectedImage.getGraphics();

g.setColor(bgColor);
g.fillRect(0, 0, w, h + reflectionHeight);

g.drawImage(image, 0, 0, Graphics.TOP | Graphics.LEFT);

int[] rgba = new int[w];
int currentY = -1;

for(int i = 0; i < reflectionHeight; i++)
{
int y = (h - 1) - (i * h / reflectionHeight);

if(y != currentY)
image.getRGB(rgba, 0, w, 0, y, w, 1);

int alpha = 0xff - (i * 0xff / reflectionHeight);

for(int j = 0; j < w; j++)
{
int origAlpha = (rgba[j] >> 24);
int newAlpha = (alpha & origAlpha) * alpha / 0xff;

rgba[j] = (rgba[j] & 0x00ffffff);
rgba[j] = (rgba[j] | (newAlpha << 24));
}

g.drawRGB(rgba, 0, w, 0, h + i, w, 1, true);
}
return reflectedImage;
}
}
MIDletReflexao.java
import java.io.IOException;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class MIDletReflexao extends MIDlet {

Display display;
private Form form;
private ImageItem imageItem;
private Image image;

public void startApp() {
display = Display.getDisplay(this);
display.setCurrent(getForm());
}

public Form getForm() {
if (form == null) {
form = new Form("Form", new Item[] { getImage() });
}
return form;
}

public ImageItem getImage() {
if (imageItem == null) {
try {
image = Image.createImage("/img.png");
} catch (IOException ex) {
ex.printStackTrace();
}
Image reflectedImage = ReflectedImage.create(image, 0xffffff, 64);
image=reflectedImage;
imageItem = new ImageItem("Reflexão", image, ImageItem.LAYOUT_DEFAULT, "Imagem perdida");
}
return (ImageItem) imageItem;
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}
}
Fonte: Classe Original: ReflectedImage.java http://wiki.forum.nokia.com/index.php

Google Phone: O SmartPhone da vez

13 dezembro 2009 0 comentários
O boato de que o Google lançaria o seu próprio smartphone para competir com o iPhone está ganhando força. Pelo Twitter, alguns funcionários disseram já ter o aparelho em mãos. As informações são de que ele seria tão fino quanto o concorrente da Apple, fabricado pela HTC e equipado com o sistema Android 2.1.

"Nós tivemos fogos de artifícios e todos nós ganhamos o novo Google Phone. Ele é lindo", twittou a a gerente de produtos open source da empresa, Leslie Hawthorn.

"O novo Google Phone tem o hardware da HTC e roda Android 2.1, que tem novos recursos visuais como planos de fundo animados". Jason Howell, repórter do site de tecnologia CNet.

Quase todos os funcionários do Google, diz ele, receberam o smartphone de presente, desbloqueado. O lançamento ficaria para o fim de janeiro de 2010, porém a empresa ainda não fez um anúncio oficial do lançamento do telefone celular.

O sistema operacional do Google já tem três versões: 1.5, 1.6 e 2.0, instalados em uma base significativa de aparelhos. O desafio dos programadores é desenvolver aplicativos que rodem satisfatoriamente em múltiplos firmwares, ROMs e hardwares. Para os usuários, o resultado vem na forma de bugs em alguns aplicativos, que podem não funcionar corretamente dependendo do aparelho e, ignorando a complexidade por trás do desenvolvimento desses programas, ficam as impressões negativas.

Será que o Android vai parar na versão 2.1 pelo menos até o fim de 2010?

Fonte:
Estadão
Mobilidade é Tudo

Trabalhando com Sprites em Java ME

02 dezembro 2009 0 comentários

Este post é sobre uma palestra do Robson Soares (blog) ministrada no Javaneiros 2009, onde ele mostra o início da construção de um Jogo em Java ME. A MIDlet construída mostra um lutador fazendo movimentos básicos de socos e chutes.

Sprite utilizado:





MIDletPrincipal.java

import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;


public class MIDletPrincipal extends MIDlet {

Display display;
Jogo meujogo;

public MIDletPrincipal() {

}

protected void destroyApp(boolean arg0) throws MIDletStateChangeException {

}

protected void pauseApp() {


}

protected void startApp() throws MIDletStateChangeException {
display = Display.getDisplay(this);
meujogo = new Jogo();

display.setCurrent(meujogo);
meujogo.inicia();

}

}

Jogo.java
import java.io.IOException;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.Sprite;


public class Jogo extends GameCanvas implements Runnable {

Sprite spritelutador;
Image lutador;

protected Jogo() {
super(true);

}

public void paint(Graphics arg0) {


try {
// lutador = Image.createImage("/lutador4.PNG");
// lutador4.PNG 900 x 188 pixels
lutador = Image.createImage("/lutador3.png");
// lutador4.PNG 468 x 98 pixels

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

// Lutador Maior
// spritelutador = new Sprite(lutador, 150, 188 );
spritelutador = new Sprite(lutador, 78, 98);

spritelutador.setFrame(0);
spritelutador.setPosition(20, 5);
spritelutador.paint(arg0);
}

public void inicia(){
Thread t = new Thread(this);
t.start();
}

public void run() {

Graphics g = getGraphics();
//int contador = 0;

while(true){
spritelutador.nextFrame();

//spritelutador.setFrame(contador++);
//if (contador == 6)
//  contador = 0;

spritelutador.paint(g);

flushGraphics();

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Relatórios com MEReport

06 novembro 2009 2 comentários

A maioria dos sistemas comerciais, seja móvel ou não, necessita de relatórios para mostrar de forma resumida a entrada e processamento dos dados. Através do blog Mobilidade é tudo descobrimos o MEReport, responsável por realizar essa tarefa de forma bastante simples.
A API ainda está sendo construída e precisando de desenvolvedores para contribuir no andamento do projeto. Quem quiser ajudar é só entrar em contato.

Segue uam prévia da classe Relatorio.java, que através da CustomItem, cria um layout de relatório com componentes personalizáveis.
import java.util.Vector;
import javax.microedition.lcdui.*;

class Relatorio extends CustomItem{
    private int minContentWidth;
    private int minContentHeight;
    
    private int prefContentHeight;
    private int prefContentWidth;
    
    private String title = "";
    private boolean titleBorder;
    private boolean titleFillColor;
    private int[] titleColorText;
    private int[] titleColorBack;
    private int[] titleColorBorder;
    private Font titleFont;
    private Font titleHeader;
    private short titleAlignment;
    
    public static final short LEFT = 0;
    public static final short CENTER = 1;
    public static final short RIGHT = 2;
    
    public String[] columnsText;
    
    public int[] columnsPercents;
    
    private boolean columnsBorder;
    private boolean columnsFillColor;
    private int[] columnsColorText;
    private int[] columnsColorBack;
    private int[] columnsColorBorder;
    private Font columnsFont;
    private short columnsAlignment;
    
    private Font textFont;
    private int[] textColor;
    private boolean textGridH;
    private boolean textGridV;
    private int[] textLinesColor;
    private Vector[] textData;
    private short textAlignment;
    
    private int[] posYInicial;
    private int[] posYFinal;
    
    private int indice;
    
    private Image imgBrasao;
    
    private int[] tamColunas;
    private int sobra;
    
    public Relatorio(int width, int height)
    {
        super("");
        
        titleFont = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_LARGE);
        titleColorText = new int[]{230, 230, 230};
        columnsColorText = new int[]{40, 40, 40};
        columnsFont = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
        textFont = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_SMALL);
        textColor = new int[]{0, 0, 0};
        
        titleAlignment = CENTER;
        titleBorder = true;
        titleColorBorder = new int[]{0, 0, 0};
        
        titleFillColor = true;
        titleColorBack = new int[]{50, 50, 50};
        
        prefContentHeight = height;
        prefContentWidth = width;
        
        minContentHeight = height;
        minContentWidth = width;
    }
    
    public void setImgBrasao(Image imgBrasao)
    {
        this.imgBrasao = imgBrasao;
    }
    
    //métodos referentes a barra superior, que contém o título
    //começo
    public void setTitle(String title)
    {
        this.title = title;
    }
    
    public void setTitleAlignment(short alignment)
    {
        this.titleAlignment = alignment;
    }
    
    public void setTitleFont(Font titleFont)
    {
        this.titleFont = titleFont;
    }
    
    public void setTitleFontHeader(Font titleFont)
    {
        this.titleHeader = titleFont;
    }
    
    public void setTitleBorder(boolean titleBorder)
    {
        this.titleBorder = titleBorder;
    }
    
    public void setTitleFillColor(boolean titleFillColor)
    {
        this.titleFillColor = titleFillColor;
    }
    
    public void setTitleColorText(int[] color)
    {
        this.titleColorText = color;
    }
    
    public void setTitleColorBack(int[] color)
    {
        this.titleColorBack = color;
    }
    
    public void setTitleColorBorder(int[] color)
    {
        this.titleColorBorder = color;
    }
    //fim
    
    //métodos referentes as colunas
    //começa
    
    public void setColumns(String[] columns)
    {
        this.columnsText = columns;
    }
    
    public void setColumnsPercents(int[] percents)
    {
        this.columnsPercents = percents;
        tamColunas = new int[columnsPercents.length];
        
        int total = 0;
        for (int i = percents.length-1; i >= 0; i--)
        {
            tamColunas[i] = ((prefContentWidth) / 100) * percents[i];
            total += tamColunas[i];
        }
        
        int sobra = ((prefContentWidth) - total) / 3;
        
        for (int i = percents.length-1; i >= 0; i--)
        {
            tamColunas[i] += sobra;
        }
    }
    
    public void setColumnsBorder(boolean columnsBorder)
    {
        this.columnsBorder = columnsBorder;
    }
    
    public void setColumnsFillColor(boolean fillColor)
    {
        this.columnsFillColor = fillColor;
    }
    
    public void setColumnsColorText(int[] color)
    {
        this.columnsColorText = color;
    }
    
    public void setColumnsColorBack(int[] color)
    {
        this.columnsColorBack = color;
    }
    
    public void setColumnsColorBorder(int[] color)
    {
        this.columnsColorBorder = color;
    }
    
    public void setColumnsFont(Font fontColumns)
    {
        this.columnsFont = fontColumns;
    }
    
    public void setColumnsAlignment(short alignment)
    {
        this.columnsAlignment = alignment;
    }
    
    //termina
    
    //métodos do texto
    //começa
    public void setTextFont(Font font)
    {
        this.textFont = font;
    }
    
    public void setTextData(Vector[] data)
    {
        this.textData = data;
    }
    
    public void setTextAlignment(short alignment)
    {
        this.textAlignment = alignment;
    }

    public void setTextColor(int[] color)
    {
        this.textColor = color;
    }
    
    public void setTextLineColor(int[] color)
    {
        this.textLinesColor = color;
    }
    
    public void setTextGridH(boolean grid)
    {
        this.textGridH = grid;
    }
    
    public void setTextGridV(boolean grid)
    {
        this.textGridV = grid;
    }
    //termina
    
    protected int getMinContentWidth() {
        return minContentWidth;
    }

    protected int getMinContentHeight() {
        return minContentHeight;
    }

    protected int getPrefContentWidth(int arg0) {
        return prefContentWidth;
    }

    protected int getPrefContentHeight(int arg0) {
        return prefContentHeight;
    }

    protected void paint(Graphics g, int largura, int altura) {
        int aux = 0;
        
        g.setColor(255, 255, 255);
        g.fillRect(0, 0, largura, altura);
        
        int tamTitulo = Math.max( (titleFont.getHeight() + 2), 
                (imgBrasao == null?0:imgBrasao.getHeight()));
        
        //espaço do título
        //se a variável titleFillColor for true significa que o usuário quer que o 
        //espaço do título seja preenchida com a cor definida no vetor 
        //titleColorBack
        if (titleFillColor) // se sim, o título tem cor de fundo
        {
            g.setColor(titleColorBack[0], titleColorBack[1], titleColorBack[2]);
            
            g.fillRect(0, 0, largura, tamTitulo);
            
            if (imgBrasao != null)
            {
                g.drawImage(imgBrasao, 0, 0, Graphics.LEFT|Graphics.TOP);
            }
        }
        
        //configura a cor que vai ser usada no título, para isso usa a variável 
        //titleColorText
        //em seguida é verificado o alinhamento escolhido para o título
        //na variável 
        //titleAlignment
        //o título está armazenado na variável 
        //title
        g.setColor(titleColorText[0], titleColorText[1], titleColorText[2]);
        g.setFont(titleFont);
        if (titleAlignment == LEFT)
            g.drawString(title, largura/2, tamTitulo/2 - titleFont.getHeight()/2, Graphics.LEFT|Graphics.TOP);
        else if (titleAlignment == CENTER)
            g.drawString(title, largura/2, tamTitulo/2 - titleFont.getHeight()/2, Graphics.HCENTER|Graphics.TOP);
        else
            g.drawString(title, largura/2, tamTitulo/2 - titleFont.getHeight()/26, Graphics.RIGHT|Graphics.TOP);
        
        //verifica se o usuário quer que o título seja contornado por uma borda
        //a variável titleBorder especifica isso
        //o vetor titleColorBorder Ccontém a cor da borda
        if (titleBorder) //verifica se o título tem borda
        {
            g.setColor(titleColorBorder[0], titleColorBorder[1], titleColorBorder[2]);
            g.drawRect(0, 0, largura, tamTitulo);
        }
        
        
        //desenha as colunas do título dos dados
        //ou seja, o cabeçalho
        aux = tamTitulo + 4;
        
        if (columnsFillColor)//se sim, as colunas tem background, senão, é transparente
        {
            int auxW = 0;
            g.setColor(columnsColorBack[0], columnsColorBack[1], columnsColorBack[2]);
            
            for (int i = 0; i < columnsText.length; i++)
            {
                g.fillRect(auxW - 1, aux, tamColunas[i]-1, 
                        titleHeader.getHeight() + 2);
                auxW += tamColunas[i];
            }
        }

        int auxW = 0;
        if (columnsBorder)
        {
            g.setColor(columnsColorBorder[0], columnsColorBorder[1], columnsColorBorder[2]);
            
            for (int i = 0; i < columnsText.length; i++)
            {
                g.drawRect(auxW - 1, aux, tamColunas[i]-1, 
                        titleHeader.getHeight() + 2);
                auxW += tamColunas[i];
            }
        }
        
        
        //escreve os títulos que representam os headers dos dados
        g.setColor(columnsColorText[0], columnsColorText[1], columnsColorText[2]);
        g.setFont(titleHeader);
        auxW = 0;
        for (int i = 0; i < columnsText.length; i++)
        {
            if (columnsAlignment == LEFT)
                g.drawString(columnsText[i], auxW, aux, Graphics.LEFT|Graphics.TOP);
            else if (columnsAlignment == RIGHT)
                g.drawString(columnsText[i], auxW + tamColunas[i] - 1, aux, 
                        Graphics.RIGHT|Graphics.TOP);
            else 
                g.drawString(columnsText[i], (auxW + tamColunas[i]/2), 
                        aux, Graphics.HCENTER|Graphics.TOP);
            auxW += tamColunas[i];
        }
        
        
        //Desenha as linhas verticais da tabela de dados
        aux += columnsFont.getHeight() + 8;
        g.setColor(0, 0, 0);
        g.drawLine(0, aux, largura, aux);
        
        if (textGridV)
        {
            g.setColor(textLinesColor[0], textLinesColor[1], textLinesColor[2]);
            
            auxW = 0;
            for (int i = 0; i < tamColunas.length-1; i++)
            {
                auxW += tamColunas[i];
                g.drawLine(auxW, aux, auxW, 
                    aux + (textFont.getHeight() * textData.length));
            }
        }
        
        //Desenha as linhas verticais da tabela de dados
        if (textGridH)
        {
            g.setColor(textLinesColor[0], textLinesColor[1], textLinesColor[2]);
            int aux2 = aux;
            for (int i = 0; i < textData.length; i++)
            {
                aux2 += textFont.getHeight();
                g.drawLine(0, aux2, largura, aux2);
            }
        }
        
        //preenche os valores da tabela
        posYInicial = new int[textData.length];
        posYFinal = new int[textData.length];
        
        g.setFont(textFont);
        for (int i = 0; i < textData.length; i++)
        {
            Vector dados = textData[i];
            auxW = 0;
            posYInicial[i] = aux;
            
            if (indice == i)
            {
                g.setColor(230, 230, 230);
                g.fillRect(0, aux+1, largura, textFont.getHeight()-1);
            }
            
            aux += textFont.getHeight();
            posYFinal[i] = aux;
            
            for (int j = 0; j < tamColunas.length; j++)
            {
                g.setColor(textColor[0], textColor[1], textColor[2]);
                if (textAlignment == LEFT)
                    g.drawString(dados.elementAt(j).toString(), auxW + 2, aux, 
                            Graphics.LEFT|Graphics.BOTTOM);
                auxW += tamColunas[j];
            }
        }
    }
    
    protected void pointerPressed(int x, int y)
    {
        for (int i = 0; i < posYFinal.length; i++)
        {
            if (y >= posYInicial[i] && y <= posYFinal[i])
            {
                indice = i;
                repaint();
                return;
            }
        }
    }
    
    protected void pointerDragged(int x, int y)
    {
    }
    
    protected void pointerReleased(int x, int y)
    {
    }
    
    protected boolean traverse(int dir, int viewportWidth, int viewportHeight, 
            int[] visRect_inout)
    {
        if (dir == 6)//pra baixo
        {
            if (indice < textData.length)
            {
                indice++;
                repaint();
                return true;
            }
            else 
            {
                return false;
            }
        }
        else if (dir == 1)//para cima
        {
            if (indice > 0)
            {
                indice--;
                repaint();
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return true;
        }
    }
    
    protected void traverseOut()
    {
        indice  = 0;
        repaint();
    }
}

A a classe MEReportMidlet.java mostra como podemos trabalhar com o MEReport.
import java.util.Vector;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class MEReportMidlet extends MIDlet {
private Display display;

private Relatorio relatorio;

private StringItem titulo;
private Form fmMain;

private Font fonte;
private Font fonte2;
private Font fonte4;

private Image imgBrasao;

public void startApp() {
display = Display.getDisplay(this);

fmMain = new Form("Relatório de Cidades");
titulo = new StringItem("Estado: ", "Rio Grande do Sul");

fmMain.append(titulo);

try{
imgBrasao = Image.createImage("/brasao.PNG");
}
catch (Exception e){
System.out.println("Erro na imagem: " + e.getMessage());
}

relatorio = new Relatorio(fmMain.getWidth(), 200);
fonte = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_LARGE);
fonte2 = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
fonte4 = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_SMALL);
relatorio.setTitle("Cidades - RS");
relatorio.setImgBrasao(imgBrasao);
relatorio.setTitleBorder(true);
relatorio.setTitleFillColor(true);
relatorio.setTitleFont(fonte);
relatorio.setTitleFontHeader(fonte2);
relatorio.setTitleColorBack(new int[]{22, 50, 117});
relatorio.setTitleColorText(new int[]{255, 255, 255});
relatorio.setTitleColorBorder(new int[]{0, 0, 0});
relatorio.setTitleAlignment(Relatorio.CENTER);
relatorio.setColumns(new String[]{"Cód.", "Cidade", "Pop."});
relatorio.setColumnsAlignment(Relatorio.LEFT);
relatorio.setColumnsBorder(true);
relatorio.setColumnsColorBorder(new int[]{0, 0, 0});
relatorio.setColumnsColorBack(new int[]{200, 200, 255});
relatorio.setColumnsColorText(new int[]{0, 0, 0});
relatorio.setColumnsFillColor(true);
relatorio.setColumnsFont(fonte);
relatorio.setTextColor(new int[]{0, 0, 0});
relatorio.setTextLineColor(new int[]{22, 50, 117});
relatorio.setTextFont(fonte2);
relatorio.setTextGridH(true);
relatorio.setTextGridV(true);

Vector[] dados = new Vector[5];
Vector passoFundo = new Vector();
passoFundo.addElement("0");
passoFundo.addElement("Passo Fundo");
passoFundo.addElement("212.700");
Vector portoAlegre = new Vector();
portoAlegre.addElement("2");
portoAlegre.addElement("Porto Alegre");
portoAlegre.addElement("1.400.500");
Vector davidCanabarro = new Vector();
davidCanabarro.addElement("3");
davidCanabarro.addElement("David Canabarro");
davidCanabarro.addElement("960.300");
Vector gramado = new Vector();
gramado.addElement("5");
gramado.addElement("Gramado");
gramado.addElement("87.000");
Vector uruguaiana = new Vector();
uruguaiana.addElement("6");
uruguaiana.addElement("Uruguaiana");
uruguaiana.addElement("134.820");
dados[0] = passoFundo;
dados[1] = portoAlegre;
dados[2] = davidCanabarro;
dados[3] = gramado;
dados[4] = uruguaiana;
relatorio.setTextData(dados);

relatorio.setColumnsPercents(new int[]{10, 58, 32});

fmMain.append(relatorio);

display.setCurrent(fmMain);
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}
}

Referência: Mobilidade é tudo

Brasil atinge 166,1 milhões de celulares

22 outubro 2009 0 comentários
Segundo Bianconi, o Brasil encerrou setembro com 166,1 milhões de celulares, com adição de 1,58 milhão de habilitações em setembro, de acordo com dados divulgados nesta quarta-feira pela Agência Nacional de Telecomunicações (Anatel).

Do total de acessos, 136,56 milhões são pré-pagos e 29,56 milhões pós-pagos.

No acumulado de janeiro a setembro, a expansão totaliza 15,5 milhões de linhas telefônicas móveis. É o segundo melhor desempenho histórico do setor para o período de nove meses, atrás apenas de igual intervalo de 2008, quando foram 19,8 milhões de novas habilitações.

A Vivo, controlada por Telefónica e Portugal Telecom, encerrou setembro com 48,8 milhões de clientes, ou 29,4 por cento do mercado total.

A Claro, do grupo mexicano América Móvil, aparece em seguida, com 42,3 milhões de assinantes, ou 25,5 por cento. Em terceiro aparece a TIM, com 39,6 milhões de clientes (23,9 por cento), seguida por Oi, com 34,8 milhões de clientes (20,9 por cento).

As participações de mercado das quatro operadoras permaneceram praticamente estáveis em setembro na comparação com agosto.

Fonte: Reuters

Capturando fotos em Java ME com a MMAPI

20 outubro 2009 0 comentários

Caso seja leigo neste assunto veja o post anterior, sobre MMAPI, que aprensenta alguns conceitos necessários para o entendimento do código que será mostrado.

Neste post mostraremos como capturar uma foto e mostrá-la em um form.

Para a captura de uma imagem é requerido instâncias de um Player, um VideoControl e um
Display.

O VideoControl é utilizado para contolar o vídeo vindo da câmera e mostrá-lo em um
form.

Primeiramente vamos criar uma instância de Player e configurá-lo para ele perceber o
estado.
// “capture://image” é usado para indicar que queremos uma imagem.
//Esta string é necessária para utilizar o método getSnapshot(), que será mostrado depois.
Player mPlayer = Manager.createPlayer("capture://image");
mPlayer.realize();
Agora inicializaremos uma instância de VideoControl e adicionaremos o vídeo em um form.
VideoControl mVideoControl=(VideoControl) mPlayer.getControl("VideoControl");
Form form = new Form("Camera form");
Item item = (Item) mVideoControl.initDisplayMode(GUIControl.USE_GUI_PRIMITIVE, null);
form.append(item);
O método getSnapshot(), do VideoControl, é utilizado para capturar as fotos. Este
método retorna um array de bytes. Para mostrar esta imagem é necessário uma instância de Image. Depois configuramos os estados dos players para fechar e setar como null nossa instância de VideoControl.
//Obtendo a imagem
byte[] raw = mVideoControl.getSnapshot(null);
Image image = Image.createImage(raw, 0, raw.length);

// Colocando o form principal.
if (this.size() > 0 && this.get(0) instanceof StringItem)
this.delete(0);
append(image);

// Volta ao form principal
mDisplay.setCurrent(this);
// desliga o player.
mPlayer.close();
mPlayer = null;
mVideoControl = null;
Ainda podemos pegar a foto que foi inserida no Form e salvá-la como uma imagem no cartão de memória do celular ou gravar no RMS, por exemplo, mas isso fica como desafio ao leitor ;)

Para baixar o projeto completo clique aqui.
É importante dizer que este código não roda no emulador.
T
estado em um Nokia 5220.

Referências:
http://efforts.embedded.ufcg.edu.br/javame/
http://developers.sun.com/mobility/apis/articles/mmapi_overview/

MMAPI

0 comentários
A Mobile Media API é uma poderosa e flexível API, que permite a renderização e captura de aúdio e vídeo. Ela permite o acesso a serviços de multimídia nativos em determinados aparelhos, permitindo a reprodução de vídeo, áudio, captura de som e imagens, utilizando o Java ME.

Para utilizar a MMAPI precisamos conhecer alguns conceitos fundamentais da API, como as classes:

- Player: um objeto utilizado para controlar e renderizar arquivos de mídia. Um Player pode tocar um determinado tipo de mídia.

- Control: utiliza-se para mudar o comportamento de um player, como aumentar o volume
do som.

- DataSource: armazenamento da mídia. Pode ser armazenada no JAR, no RMS, no sistema
de arquivos do celular, sendo acessado via File Connection API, entre outros modos.

- Manager: responsável pelo acesso a recursos do sistemas como Players para o processamento de multimídia. Ele serve de ponte entre as interfaces citadas a cima. E além de obter Players permite a obtenção de DataSources.

O relacionamento destas classes é ilustrado na figura abaixo:
Estes conceitos são necessários tanto para capturar fotos, como gravar vídeos e tocar músicas.

No próximo post iremos mostrar como fazer para capturar fotos.


Referências:
http://developers.sun.com/mobility/apis/articles/mmapi_overview/
http://efforts.embedded.ufcg.edu.br/javame/

TIM anuncia loja de aplicativos

18 outubro 2009 0 comentários
Em parceira com a Qualcomm, loja terá aplicativos compatíveis com quase todos os celulares da Tim.

A fabricante de chips Qualcomm e a operadora TIM anunciaram a oferta de uma loja de aplicativos para celulares com o uso da solução Plaza Retail, desenvolvida pela Qualcomm, para o primeiro trimestre de 2010.

A plataforma foi desenvolvida para a criação de aplicativos capazes de rodar na maior parte dos aparelhos celulares presentes na operadora. A vitrine abriga softwares projetados para as plataformas Java, BREW Flash e Android. Já se planeja, também, suporte para Windows Mobile, Palm, Symbian e LiMo.

Segundo o diretor de marketing da TIM, Rogério Takayamagi, a expectativa de lançar a loja até março do próximo ano é realista. "Antes do lançamento, é necessário realizar testes de integração e ter a certeza que que a loja funciona para a maior quantidade possível de usuários", afirma.

Para Len Lauer, chefe de operações da Qualllcom, os fabricantes de aparelhos que produzem aplicativos são concorrentes, mas a empresa aposta na diversidade de plataformas e na cobrança integrada para ganhar espaço contra esses concorrentes.

Takayamagi disse também que a característica aberta da loja de aplicativos vai permitir que os desenvolvedores criem inclusive softwares corporativos, voltados para produtividade. "Se existe demanda, vai haver alguém para desenvolver aplicativos para qualquer nicho de mercado".

Essa é a hora de investir no Java ME!

Fonte: IDGNOW

Android, uma esperança para a Motorola

15 outubro 2009 2 comentários
Qual o último aparelho da motorola que fez sucesso? Se você pensou no V3 então deve concordar que ela estava meio sumida. Mas nesta quarta-feira (14), aconteceu o lançamento do smartphone MotoDext no Brasil. Equipado com o sistema operacional Android, será vendido pela operadora Claro a partir da segunda metade de novembro. O aparelho possui o Motoblur, uma alteração no sistema voltado para redes sociais.


A empresa considera o aparelho, chamado de Cliq nos Estados Unidos, como o maior do ano. Além do Android, ele possui teclado QWERTY, tela sensível ao toque de 3,1 polegadas, Wi-Fi, GPS, 3G e câmera de 5 MP com capacidade de gravar vídeos.

O celular roda o novo tema Motoblur Android, construído para utilizar interação com redes sociais, com widgets (aplicativos) que integram Twitter, Facebook, Gmail, MySpace, Yahoo!, Last.fm e mais. A Motorola está chamando o smartphone de "o primeiro telefone com habilidades sociais", enaltecendo o recurso.

O preço médio do MotoDext pela Claro (com exclusividade até o começo de 2010) será de R$ 1.599,00

Sun SPOT

28 setembro 2009 0 comentários
Sun SPOT (Sun Small Programmable Object Technology) é um dispositivo de comunicação eletrônico, desenvolvido pela Sun, que utiliza redes sem fio para a comunicação. É baseado na máquina virtual Java ME e, totalmente montado, cabe na palma de uma mão.

O projeto Sun SPOT foi criado para encorajar o desenvolvimento de novas aplicações e dispositivos. Ele permite que desenvolvedores que nunca trabalharam com dispositivos embarcados pensem além do mouse e teclado e escrevam programas que interagem com outros dispositivos.

O Sun SPOT é muito mais que um microprocessador embarcado que roda Java. Ele abriga uma série de tecnologias necessárias para conectar objetos.

Estrutura do SPOT:

Placa Mãe
-> Micro controlador Atmel AT91RM9200 baseado no Processador ARM920T Core 32 bits, com 180 MHz, 512 KB RAM e 4MB de Flash;
-> Antena de rádio Integrada na placa, padrão IEEE 802.15.04 de 2.4 GHz (O rádio é um CC2420 TI);
-> Cada processador tem uma interface USB (que serve de alimentação para a bateria);
-> Há um micro controlador 8-bits ATmega88 Atmel usado como um controlador de potência.

Placa de Sensores
-> Acelerômetro 2G/6G 3-axis;
-> Sensor de Temperatura;
-> Sensor de Luz;
-> 8 LEDs tri-coloridos;
-> 6 entradas analógicas por ADC;
-> 2 sensores de movimento (switches);
-> 5 Pinos I/O de própósito geral e 4 pinos de alta corrente de saída;

Bateria
-> Bateria recarregável de lítio-ion de 3.6 V e 750 mAh;
-> Modo de inatividade (ou sleep) profundo a 48 uA;
-> Gerenciamento automático de bateria provido pelo software.

Sua máquina virtual baseada em Java ME chama-se Squawk e roda diretamente no processador, sem utilizar o sistema operacional. Esta VM executa plenamente códigos J2ME CLDC 1.1, diretamente na memória flash.

As ferramentas para desenvolvimento de aplicações são IDE’s padrão (Eclipse, NetBeans), acompanhadas de um plugin.

O Sun SPOT possui ainda um emulador no qual poderão ser testadas as aplicações que futuramente rodarão no dispositivo. Além de todas as funcionalidades do spot, destacamos o fato de poderem ser simulados vários spots na ferramenta.

O software é compatível com Windows XP, Mac OS X 10.4 e com as distribuições mais comuns do Linux.

Quanto a segurança, ele possui implementações altamente otimizadas dos algoritmos RSA e ECC (Criptografia de Curvas Elípticas).

Entre as vantagens de se utilizar o SPOT, estão:
- Totalmente baseado em Java, tornando fácil a programação e a integração em aplicações em rede;
- Diferentes aplicações podem ser executadas ao mesmo tempo sem precisar de várias máquinas virtuais;
- O desenvolvedor pode iniciar, parar ou executar aplicações a partir de um dispositivo para outro;
- Possui um consumo de energia muito baixo;
- Trabalha análogo ao Java em relação à coleta de lixo (garbage collection);
- É um dispositivo bastante poderoso com um processador de 32 bits com lotes de fácil acesso I/O para experimentação;

Entre as desvantagens estão:
- O preço, cerca de U$750,00.
- Dificuldade de obter o kit. Por enquanto não estão disponíveis para venda no Brasil. Porém através de universidades é possível conseguir alguns kits.

Veja alguns vídeos muito interessantes do uso de Sun SPOTS

SUN SPOT Game Controller for Counter Strike



Sun SPOT Telerobotics



Para quem estiver interessado em começar a brincar com o Sun SPOT veja os links:
- [Tutorial] Aprendendo a Mexer com o Sun SPOTS
- Iniciando SUN Spot com NetBeans 6.1

Referências
http://www.sunspotworld.com/
http://blogs.sun.com/cindydalfovo/entry/tutorial_aprendendo_a_mexer_com

Scrum

24 setembro 2009 0 comentários

Quando o assunto é gerenciamento de projetos, Scrum, trata-se de uma metodologia ágil, porém surgiu a partir de um jogo conhecido como Rugby. Neste jogo, o scrum é uma jogada que envolve oito jogadores de cada time, onde eles se "encaixam", para se tornar uma muralha. O grande ponto dessa jogada é a vital importância do trabalho em equipe. Se um membro falhar na formação, já era, o outro time se sobressai.

É justamente pela importância desse trabalho integrado do time, que esta palavra foi utilizada como nome da metodologia. O fundamental é o time trabalhar junto! As pessoas são importantes e é por isso que resultados fantásticos são alcançados com essa metodologia. A função primária do Scrum é ser utilizado para o gerenciamento de projetos de desenvolvimento de software. Ele tem sido usado com sucesso para isso, assim como Extreme Programming e outras metodologias de desenvolvimento.

No Scrum, os projetos são dividos em ciclos (tipicamente mensais) chamados de Sprints. O Sprint representa um Time Box dentro do qual um conjunto de atividades deve ser executado. Metodologias ágeis de desenvolvimento de software são iterativas, ou seja, o trabalho é dividido em iterações, que são chamadas de Sprints no caso do Scrum.

As funcionalidades a serem implementadas em um projeto são mantidas em uma lista que é conhecida como Product Backlog. No início de cada Sprint, faz-se um Sprint Planning Meeting, ou seja, uma reunião de planejamento na qual o Product Owner prioriza os itens do Product Backlog e a equipe seleciona as atividades que ela será capaz de implementar durante o Sprint que se inicia. As tarefas alocadas em um Sprint são transferidas do Product Backlog para o Sprint Backlog.

A cada dia de uma Sprint, a equipe faz uma breve reunião (normalmente de manhã), chamada Daily Scrum. O objetivo é disseminar conhecimento sobre o que foi feito no dia anterior, identificar impedimentos e priorizar o trabalho do dia que se inicia.

Ao final de um Sprint, a equipe apresenta as funcionalidades implementadas em uma Sprint Review Meeting. Finalmente, faz-se uma Sprint Retrospective e a equipe parte para o planejamento do próximo Sprint. Assim reinicia-se o ciclo.

Veja:


Um pouco mais de Scrum


1) Product Owner: É a pessoa que define os itens que compõem o Product Backlog e os prioriza nas Sprint Planning Meetings.

O Scrum Team olha para o Product Backlog priorizado, seleciona os itens mais prioritários e se compromete a entregá-los ao final de um Sprint (iteração). Estes itens transformam-se no Sprint Backlog.

A equipe se compromete a executar um conjunto de atividades no Sprint e o Product Owner se compromete a não trazer novos requisitos para a equipe durante o Sprint. Requisitos podem mudar (e mudanças são encorajadas), mas apenas fora do Sprint. Uma vez que a equipe comece a trabalhar em um Sprint, ela permanece concentrada no objetivo traçado para o Sprint e novos requisitos não são aceitos.

2) Sprint Planning Meeting: É uma reunião na qual estão presentes o Product Owner, o Scrum Master e todo o Scrum Team, bem como qualquer pessoa interessada que esteja representando a gerência ou o cliente.

Durante o Sprint Planning Meeting, o Product Owner descreve as funcionalidades de maior prioridade para a equipe. A equipe faz perguntas durante a reunião de modo que seja capaz de quebrar as funcionalidades em tarefas técnicas, após a reunião. Essas tarefas irão dar origem ao Sprint Backlog.

O Product Owner não precisa descrever todos os itens que estão no Product Backlog. Dependendo do tamanho do Product Backlog e da velocidade da equipe, pode ser suficiente descrever apenas os itens de maior prioridade, deixando a discussão dos itens de menor prioridade para o próximo Sprint Planning Meeting.

Coletivamente, o Scrum Team e o Product Owner definem um objetivo para o Sprint, que é uma breve descrição daquilo que se tentará alcançar no Sprint. O sucesso do Sprint será avaliado mais adiante no Sprint Review Meeting em relação ao objetivo traçado para o Sprint.

Depois do Sprint Planning Meeting, a equipe Scrum se encontra separadamente para conversar sobre o que eles escutaram e decidir quanto eles podem se comprometer a fazer no Sprint que será iniciado. Em alguns casos, haverá negociação com o Product Owner, mas será sempre responsabilidade da equipe determinar o quanto ela será capaz de se comprometer a fazer.

3) Product Backlog: É uma lista contendo todas as funcionalidades desejadas para um produto. O conteúdo desta lista é definido pelo Product Owner. O Product Backlog não precisa estar completo no início de um projeto. Pode-se começar com tudo aquilo que é mais óbvio em um primeiro momento. Com o tempo, o Product Backlog cresce e muda à medida que se aprende mais sobre o produto e seus usuários.

Durante o Sprint Planning Meeting, o Product Owner prioriza os itens do Product Backlog e os descreve para a equipe. A equipe então determina que itens será capaz de completar durante a Sprint que está por começar. Tais itens são, então, transferidos do Product Backlog para o Sprint Backlog. Ao fazer isso, a equipe quebra cada item do Product Backlog em uma ou mais tarefas do Sprint Backlog. Isso ajuda a dividir o trabalho entre os membros da equipe. Podem fazer parte do Product Backlog tarefas técnicas ou atividades diretamente relacionadas às funcionalidades solicitadas.

4) Sprint Backlog: É uma lista de tarefas que o Scrum Team se compromete a fazer em um Sprint. Os itens do Sprint Backlog são extraídos do Product Backlog, pela equipe, com base nas prioridades definidas pelo Product Owner e a percepção da equipe sobre o tempo que será necessário para completar as várias funcionalidades.

Cabe a equipe determinar a quantidade de itens do Product Backlog que serão trazidos para o Sprint Backlog, já que é ela quem irá se comprometer a implementá-los.

Durante um Sprint, o Scrum Master mantém o Sprint Backlog atualizando-o para refletir que tarefas são completadas e quanto tempo a equipe acredita que será necessário para completar aquelas que ainda não estão prontas. A estimativa do trabalho que ainda resta a ser feito no Sprint é calculada diariamente e colocada em um gráfico, resultando em um Sprint Burndown Chart.

5) A cada dia do Sprint a equipe faz uma reunião diária, chamada Daily Scrum. Ela tem como objetivo disseminar conhecimento sobre o que foi feito no dia anterior, identificar impedimentos e priorizar o trabalho a ser realizado no dia que se inicia.

Os Daily Scrums normalmente são realizadas no mesmo lugar, na mesma hora do dia. Idealmente são realizados na parte da manhã, para ajudar a estabelecer as prioridades do novo dia de trabalho.

Todos os membros da equipe devem participar do Daily Scrum. Outras pessoas também podem estar presentes, mas só poderão escutar. Isso torna os Daily Scrums uma excelente forma para uma equipe disseminar informações sobre o estado do projeto.

O Daily Scrum não deve ser usado como uma reunião para resolução de problemas. Questões levantadas devem ser levadas para fora da reunião e normalmente tratadas por um grupo menor de pessoas que tenham a ver diretamente com o problema ou possam contribuir para solucioná-lo. Durante o Daily Scrum, cada membro da equipe provê respostas para cada uma destas três perguntas:

* O que você fez ontem?
* O que você fará hoje?
* Há algum impedimento no seu caminho?

Concentrando-se no que cada pessoa fez ontem e no que ela irá fazer hoje, a equipe ganha uma excelente compreensão sobre que trabalho foi feito e que trabalho ainda precisa ser feito. O Daily Scrum não é uma reunião de status report na qual um chefe fica coletando informações sobre quem está atrasado. Ao invés disso, é uma reunião na qual membros da equipe assumem compromissos perante os demais.

Os impedimentos identificados no Daily Scrum devem ser tratados pelo Scrum Master o mais rapidamente possível.

6) Sprint Review Meeting: Feito ao final de cada Sprint, nesta reunião, o Scrum Team mostra o que foi alcançado durante o Sprint. Tipicamente, isso tem o formato de um demo das novas funcionalidades.

Os participantes do Sprint Review tipicamente incluem o Product Owner, o Scrum Team, o Scrum Master, gerência, clientes e engenheiros de outros projetos.

Durante o Sprint Review, o projeto é avaliado em relação aos objetivos do Sprint, determinados durante o Sprint Planning Meeting. Idealmente, a equipe completou cada um dos itens do Product Backlog trazidos para fazer parte do Sprint, mas o importante mesmo é que a equipe atinja o objetivo geral do Sprint.

7) Sprint Retrospective: Ocorre ao final de um Sprint e serve para identificar o que funcionou bem, o que pode ser melhorado e que ações serão tomadas para melhorar.


8) Quem usa Scrum?

- Google
- Microsoft
- Yahoo
- Nokia
- Siemens
- UOL
- Philips
- Electronic Arts
- BBC
entre outros...

Referências:
http://blogs.abril.com.br/scrum/2008/08/que-scrum-metodologia-agil.html
http://improveit.com.br/scrum
http://www.slideshare.net/tatix/batepapo-sobre-scrum-e-design-looping-rbs
http://www.mountaingoatsoftware.com/system/hidden_asset/file/52/PortugueseScrum.pdf

Veja mais na InfoQ:
http://www.infoq.com/br/bycategory/newsbycategory.action?idx=15&alias=scrum

Just Java 2009: Uma visão móvel

22 setembro 2009 0 comentários
O Java Móvel esteve presente no Just Java 2009, que aconteceu nos dias 15, 16 e 17 de setembro, e neste post fica nossas considerações sobre mobilidade e desenvolvimento em Java ME, TV Digital, desenvolvimento ágil e assuntos que nos chamou mais atenção.


Já no inicio do evento Daniel Ambrósio, representante da UOL, mostrou o sucesso do Scrum na empresa, implantado a cerca de um ano, pra quem não conhece essa metodologia, no próximo post vamos explorar o tema.

A palestra Java ME 360 graus - Do Sun Spot à TV Digital, de Antonio Marin Neto (Instituto Nokia) e Igor Medeiros(JavaCard man), mostrou que o java me vai muito além do desenvolvimento para celulares, podendo ser utilizado na robótica, telemetria, TV Digital e a novidade que trouxeram, a caneta que roda Java. Comentaram um pouco de JavaCard, que correspondem a 95% dos SIM Cards (chips de celular).
Mostraram que em um fururo breve serão usados e-CPF e RG Digital com Java Card, o que torna a área ainda mais promissora. Ainda foi comentado que a comunicação do javacard será via HTTP, utilizando servlets para tal tarefa.
Eles ainda apresentaram uma brincadeira com o SunSpot e comentaram sobre o LWUIT, enfatizando seu uso em aplicações para TV Digital.

Falando em TV Digital, Aguinaldo Boquimpani comentou sobre a interatividade na TV Digital. Nos bastidores do evento, comentamos sobre quem poderia realmente comercializar aplicações para TV. E se as aplicações serão disponibilizadas pelas emissoras de TV, então quem venderá tais aplicações senão elas? Os desenvolvedores serão apenas internos da empresa ou terceiros poderão verder suas aplicações também? Fica aí a força do Middleware Aberto do Sistema Brasileiro de TV Digital - Ginga.

Este contexto tráz uma nova visão, os conhecimentos técnicos não bastam para os candidatos a trabalhar com TV digital. Eles terão que ter também muita criatividade e a consciência de que estarão lidando com um meio – e um público – bastante diferente.

Segundo Aguinaldo Boquimpani, a verdadeira batalha desse mercado será criar aplicações que ganhem o coração do telespectador. Para isso, os desenvolvedores deverão ter em mente que estão lidando com um mundo novo. O ambiente da TV é totalmente diferente do ambiente no PC ou mesmo no celular . Quem achar que a TV digital será uma Internet na TV não será bem-sucedido. Os profissionais de TI, principalmente de software e design, terão obrigatoriamente que se reciclar para entender as imensas diferenças e o enorme potencial desse novo ambiente.

Neto Marin também palestrou sobre aplicativos Java ME para Devices touch Screen, mostrando dicas sobre usabilidade, como:

- Criar interfaces intuitivas;
- Estimulos visuais ao usuário (cores, botões e slides);
- Evitar inputs por digitação;
- Evitar ícones e textos pequenos;
- Mostrar um feedback visual para teclados virtuais;
- Enfim, é importante desenvolver aplicativos com interfaces simples para atingir usuários que não dominam tecnologia.

Surge aí mais uma vez a importância do LWUIT, que já trata o pressionamento de teclas em dispositivos touch screen, sem a necessida de trabalhar com Canvas - baixo nível.

Com Maurício Leal, Gerente de Programas SDN (Sun Developer Networks) para a América Latina da Sun Microsystems, foi mostrado a importância do JavaFX, plataforma para criação de conteúdo para aplicações RIA. O JavaFX script atende Desktop, Mobile e Web com o mesmo fonte. Apresentou uma aplicação onde é usado um plugin no Photoshop para o designer da aplicação, onde cada camada se torna uma figura separada para ser tratada no código. Pelo que tudo indica o JavaFX (eféx, rs) é o futuro das aplicações RIA!

Na palestra Do with LWUIT de Roger Brinkley, Líder Comunitário da Comunidade Móvel & Embarcados da Sun Microsystems (EUA), foi mostrado as características do LWUIT, como: roda em CDC/CLDC, suporte a touch Screen, transições, temas, etc. Lembrando que a SUN incluiu o LWUIT recentemente como uma biblioteca padrão, e mostra o framework para todo o mundo ver a importância que ele tem tanto para aplicaçôes em java ME quanto para TV Digital.

Robison Cris Brito ministrou uma palestra sobre Desenvolvimento de Jogos para celular com o Game Builder do NetBeans, mostrando o quanto a ferramenta facilita o desenvolvimento. Com a ferramenta ainda é necessário a codificação da lógica, porém o layout não precisa ser feito a mão. O Robison fez a demonstração de um game que já vem no netbeans (Karel x Thomas), explicando os métodos principais e fazendo uma nova fase para o jogo, depois demostrou rapidamente a criação de um jogo de nave, este iniciado do zero. Vale ressaltar que o Game Builder vem apartir do Netbeans 6.0 e é desenvolvido com o perfil MIDP 2.0. Enfim, é uma ótima ferramenta para os interessados em desenvolvimento de jogos para celular.

José Donizetti de Brito e Paulo Silveira da CAELUM ministraram a palestra Desmistificando o TDD na prática, (TDD - Test Driven Development) onde defenderam a idéia de escrever testes antes de criar o código (ao estilo do XP), pois escrevendo os testes antes tornam-se visíveis quais métodos são realmente necessários. Fizeram um exemplo prático com ajuda do público e mostraram as várias falhas que o sistema possuía e que quase ninguém notou. Criaram vários testes de Unidade com o framework JUnit, onde podemos enxergar o porque as falhas ocorriam, fatos que não são facilmente observados durante a programação. Com JUnit, o programador tem uma ferramenta que o ajudará a eliminar os erros de seu código de maneira mais atraente.

Concluímos dizendo que o evento foi realmente interessante! Esperamos ter ajudado a quem não pode ir no evento e está interessado em mobilidade e desenvolvimento em Java ME e outros assuntos relacionados.

Android 1.6 está pronto para desenvolvedores

20 setembro 2009 0 comentários

O Google disponibilizou uma nova versão do Android, destinada aos desenvolvedores de
aplicativos, no formato SDK (Software Developer Kit).

O pacote oferece updates e novas ferramentas aos programadores, como:

- capacidade de reconhecer gestos com o aparelho. Desenvolvedores poderão produzir aplicativos sensíveis às diferentes formas de toque na tela do aparelho.
- upgrade no sistema de fotografia e filmagem. Ativar uma câmera em um aparelho deve ficar 39% mais rápido. O tempo de espera entre a aquisição de fotos deve cair para 28%.
- A resolução dos aplicativos não está mais presa ao hardware e pode ser ajustada pelos programadores.

Outras alterações incluem o recurso Text-to-Speech, alteração da Market UI e renovação do
indicador de bateria. Agora é possível ver quais aplicativos estão consumindo mais energia do aparelho e desligá-los.

Referência
http://info.abril.com.br/noticias/ti/android-1.6-esta-pronto-para-desenvolvedores-16092009-
4.shl

Sansung estreia Android no Brasil

0 comentários

A HTC havia informado que seria a primeira a trazer aparelhos com Android para o mercado brasileiro. Porém a Sansung passou a frente e já iniciou a distribuição do primeiro celular com Android a ser vendido no Brasil, o Galaxy i7500.

O dispositivo tem tela de 3.2´ sensível ao toque, suporta redes 3G e conexão Wi-Fi. Além disso, o Galaxy conta com câmera de 5 MP e memória interna de 8 GB, expansível até 32GB, mesma capacidade de armazenamento do modelo mais avançado da Apple, o iPhone 3GS de 32 GB.



O preço de R$ 1799 sugerido pela Samsung pode variar um pouco e, na prática, ficar mais em conta dependendo do plano de dados contratado e do subsídio oferecido pela operadora.

Os aparelhos chegam aos fornecedores esta semana e estarão disponiveis aos compradores na segunda quinzena de outubro. A primeira operadora que irá disponibiliza-los será a TIM.

Referência
http://info.abril.com.br/noticias/tecnologia-pessoal/samsung-estreia-android-no-brasil-17092009-26.shl

Usando a PIM API para acessar listas do Mobile

11 setembro 2009 5 comentários

Como já vimos em posts anteriores, a JSR 75 especifica dois pacotes obrigatórios para a plataforma Java ME.
Um deles é o PIM - Pacote que permite desenvolvedores realizar CRUD (criar, recuperar, atualizar e excluir), acessando os dados de PIM do aparelho, tais como agenda, livro de endereços e listas de tarefas, que existe na maioria dos dispositivos móveis.
É importante saber que nem todos os dispositivos suportam a PIM API e que alguns podem ter mais de um banco de dados pessoal.

Os objetivos principais deste pacote opcional são:

-Proporcionar o acesso aos dados pessoais em formatos nativos, o que poderá residir no dispositivo, em mídia removível, ou em algum lugar sobre a rede;
-Suporte à importação e exportação de endereços do catálogo em formato vCard e agenda, e fazer cadastros em formato vCalendar;
-Não impõe campos ou atributos obrigatórios;
-Garantir a segurança na utilização destas APIs.

O pacote opcional PIM define três tipos de dados de PIM, conhecido como listas PIM:

-As listas de contatos, que contêm nomes, endereços, números de telefone e outras informações sobre negócios e contatos pessoais;
-Lista de eventos, compromissos, lembretes, data e outros itens específicos;
-Listas de tarefas, as tarefas que o usuário precisa realizar.

As APIs do PIM estão definidas no pacote javax.microedition.io.pim. Este pacote é composto por oito interfaces e seis classes, incluindo quatro tipos de exceção:

Descrição das Interfaces

-PIMItem: A superinterface comum de um item a ser armazenado em uma lista do PIM;
-PIMList: A superinterface comum de ContactList, EventList e ToDoList, cada um dos quais pode conter zero ou mais PIMItems;
-Contact: uma única entrada em um banco de contato, os campos estáticos nesta interface são um subconjunto dos campos definido pela especificação vCard;
-ContactList: Uma lista de itens de Contato;
-Event: Entrada única no banco de eventos;
-EventList: Uma lista de itens do evento;
-ToDo: Entrada única no banco de afazeres;
-ToDoList: Uma lista de itens para fazer.

Descrição das Classes

-PIM: Fornece um conjunto de métodos estáticos para encontrar informações e para acessar PIMLists;
-RepeatRule: A descrição de um padrão de repetição de um item do evento, para especificar quando o evento associado ocorrerá (os campos estáticos dessa classe são um subconjunto dos recursos do campo RRULE em VEVENT, definido pela especificação vCalendar 1.0);
-FieldEmptyException: acionada quando uma tentativa é feita para acessar um campo que não tem dados com valores a ele associados;
-FieldFullException: acionada quando uma tentativa é feita para adicionar dados a um campo cujos valor dos dados disponíveis já foram atribuídos;
-PIMException: geradas pelas classes PIM;
-UnsupportedException: Acionada quando o campo de referência não é suportado na lista PIM que um elemento pertence.

O pacote PIM poderá não estar disponíveil em todas as plataformas Java ME. Para saber se algum dispositivo implementa tal pacote opcional, chame o método System.getProperty(microedition.pim.version). O método irá retornar o número da versão da API se é suportado, ou nulo se não é.

Para exemplificar segue a implementação de duas classes:

PIMMidlet.java


import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class PIMMidlet extends MIDlet {
ReadPIM readPim;
Display display;

public void startApp(){
display = Display.getDisplay(this);
readPim = new ReadPIM(this);
display.setCurrent(readPim);
}

public void pauseApp(){
}

public void destroyApp(boolean uc){
}
}
ReadPIM.java

import javax.microedition.lcdui.*;
import javax.microedition.pim.*;
import java.util.*;

public class ReadPIM extends Form implements Runnable, CommandListener{
PIM pim;
PIMList pimlist;
Contact contact=null;
Enumeration enumeration;
PIMMidlet midlet;

String contactName="";
String contactNo="";

Thread thread=null;
Command exitCmd = new Command("Sair",Command.EXIT,1);

public ReadPIM(PIMMidlet midlet){
super("Lendo Contatos");
this.midlet = midlet;

pim = PIM.getInstance();

thread = new Thread(this);
thread.start();
addCommand(exitCmd);
setCommandListener(this);

}

public void run(){
readContacts();
}

public void readContacts(){

String[] lists = pim.listPIMLists(PIM.CONTACT_LIST);

for (int i = 0; i < pimlist =" pim.openPIMList(PIM.CONTACT_LIST,PIM.READ_WRITE);" enumeration =" pimlist.items();" contact =" (Contact)enumeration.nextElement();">0))
contactName = contact.getString(Contact.FORMATTED_NAME,0);

if(pimlist.isSupportedField(Contact.TEL) &&(contact.countValues(Contact.TEL) >0))
contactNo = contact.getString(contact.TEL,0)+"\n\n";
append("\nNome: "+contactName+"\nTelefone: "+contactNo);
}

}catch( Exception e){}
}
}

public void commandAction(Command c , Displayable d){
if(c == exitCmd){
midlet.destroyApp(true);
midlet.notifyDestroyed();
}
}
}
Referências
http://developers.sun.com/mobility/apis/articles/pim/index.html

Propriedades do sistema com MIDP

07 setembro 2009 1 comentários

Olá! este breve post é simplesmente para mostrar um documento que a Nokia diponibilizou, apresentando funções que enumeram as propriedades do sistema que podem ser recuperadas usando o método System.getProperty().
O pacote também inclui uma documentação e um pequeno MIDlet para verificação das propriedades do sistema afim de saber o que o dispositivo suporta.


Seguem as Classes


Classe SysPropForm.java

import javax.microedition.lcdui.*;
import javax.bluetooth.LocalDevice;

public class SysPropForm extends Form implements CommandListener {
private Command backCommand;
private Command exitCommand;
private SystemProperties midlet;

public SysPropForm(String title, SystemProperties midlet, String[] list) {
super(title);
this.midlet = midlet;
backCommand = new Command("Back", Command.BACK, 1);
exitCommand = new Command("Exit", Command.EXIT, 1);
addCommand(backCommand);
addCommand(exitCommand);
setCommandListener(this);

for (int i = 0; i < c ="=" bt =" false;" c ="=">

Classe SystemProperties.java

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class SystemProperties extends MIDlet implements CommandListener {
private static final String[] SYSPROPLISTS = {
"CLDC&MIDP", "Optional packages", "MMAPI", "Bluetooth API",
"FileConnection API", "WMA", "SATSA", "Other"};
private static final String[] CLDC_MIDPPROPS = {
"microedition.profiles", "microedition.configuration", "microedition.locale",
"microedition.platform", "microedition.encoding", "microedition.commports",
"microedition.hostname", "microedition.jtwi.version"};
private static final String[] OPT_SYSPROPS = {
"microedition.media.version", "microedition.pim.version",
"microedition.io.file.FileConnection.version", "microedition.m3g.version",
"microedition.location.version", "microedition.global.version",
"microedition.chapi.version", "microedition.sip.version"};
private static final String[] MMAPI_SYSPROPS = {
"supports.mixing", "supports.audio.capture", "supports.video.capture",
"supports.recording", "audio.encodings", "video.encodings",
"video.snapshot.encodings", "streamable.contents"};
private static final String[] BT_SYSPROPS = {
"bluetooth.api.version", "bluetooth.l2cap.receiveMTU.max",
"bluetooth.connected.devices.max", "bluetooth.connected.inquiry",
"bluetooth.connected.page", "bluetooth.connected.inquiry.scan",
"bluetooth.connected.page.scan", "bluetooth.master.switch",
"bluetooth.sd.trans.max", "bluetooth.sd.attr.retrievable.max"};
private static final String[] FILE_API_SYSPROPS = { "fileconn.dir.photos",
"fileconn.dir.videos", "fileconn.dir.tones", "fileconn.dir.memorycard",
"fileconn.dir.private", "fileconn.dir.photos.name", "fileconn.dir.videos.name",
"fileconn.dir.tones.name", "fileconn.dir.memorycard.name", "file.separator"};
private static final String[] WMA_SYSPROPS = {
"wireless.messaging.sms.smsc"};
private static final String[] SATSA_SYSPROPS = {
"microedition.smartcardslots"};
private static final String[] OTHER_SYSPROPS = {
"com.nokia.mid.dateformat", "com.nokia.mid.timeformat",
"com.nokia.network.access", "com.nokia.mid.imei"};
private List list;
private SysPropForm cldcmidpform;
private SysPropForm optform;
private SysPropForm mmapiform;
private SysPropForm btform;
private SysPropForm fileapiform;
private SysPropForm wmaform;
private SysPropForm satsaform;
private SysPropForm otherform;
private Command exitCommand;
protected boolean bt = false;

public SystemProperties() {
list = new List("System properties", List.IMPLICIT, SYSPROPLISTS, null);
exitCommand = new Command("Exit", Command.EXIT, 1);
list.addCommand(exitCommand);
list.setCommandListener(this);
Display.getDisplay(this).setCurrent(list);
}

protected void startApp() throws MIDletStateChangeException {
}

protected void pauseApp() {
}

protected void destroyApp(boolean p1) {
}

public void commandAction(Command c, Displayable d) {
if (c == List.SELECT_COMMAND) {
int index = list.getSelectedIndex();
if (index == 0) {
cldcmidpform = new SysPropForm(SYSPROPLISTS[0], this, CLDC_MIDPPROPS);
Display.getDisplay(this).setCurrent(cldcmidpform);
}
if (index == 1) {
optform = new SysPropForm(SYSPROPLISTS[1], this, OPT_SYSPROPS);
Display.getDisplay(this).setCurrent(optform);
}
if (index == 2) {
mmapiform = new SysPropForm(SYSPROPLISTS[2], this, MMAPI_SYSPROPS);
Display.getDisplay(this).setCurrent(mmapiform);
}
if (index == 3) {
bt = true;
btform = new SysPropForm(SYSPROPLISTS[3], this, BT_SYSPROPS);
Display.getDisplay(this).setCurrent(btform);
}
if (index == 4) {
fileapiform = new SysPropForm(SYSPROPLISTS[4], this, FILE_API_SYSPROPS);
Display.getDisplay(this).setCurrent(fileapiform);
}
if (index == 5) {
wmaform = new SysPropForm(SYSPROPLISTS[5], this, WMA_SYSPROPS);
Display.getDisplay(this).setCurrent(wmaform);
}
if (index == 6) {
satsaform = new SysPropForm(SYSPROPLISTS[6], this, SATSA_SYSPROPS);
Display.getDisplay(this).setCurrent(satsaform);
}
if (index == 7) {
otherform = new SysPropForm(SYSPROPLISTS[7], this, OTHER_SYSPROPS);
Display.getDisplay(this).setCurrent(otherform);
}
}
if (c == exitCommand) {
quitApp();
}
}

public void quitApp() {
destroyApp(true);
notifyDestroyed();
}

protected void showList() {
Display.getDisplay(this).setCurrent(list);
}
}


Links:
http://www.forum.nokia.com/info/sw.nokia.com/id/37086440-dcce-4fb4-aa3e-8d8c16d62b33/MIDP_System_Properties_v1_2_en.zip.html

http://www.forum.nokia.com/info/sw.nokia.com/id/bd70d77a-f82f-47ce-a4f8-ca3d868e60a8/MIDP_System_Properties_v1_1.zip.html

Nokia lança seu primeiro celular com Linux

28 agosto 2009 0 comentários
Segundo HELSINQUE (Reuters), a Nokia, maior fabricante de celulares do mundo, lançou nesta quinta-feira seu primeiro aparelho sofisticado que utiliza sistema operacional Linux.

O novo modelo N900, com conexão de celular, tela sensível a toque e teclado deslizante, custa em torno de 500 euros (712 dólares) no varejo, sem considerar subsídios e impostos.

O sistema operacional de fonte aberta Symbian, da Nokia, controla metade do volume do mercado de smartphones, mais que os concorrentes Apple, Research in Motion e Google juntos.
A companhia informou que o Linux funcionará paralelamente ao Symbian na série de produtos sofisticados.

"Isso não está colocando o Symbian de modo algum em perigo", afirmou Anssi Vanjoki, diretor de vendas da Nokia, à Reuters.

"O código aberto Symbian será nossa principal plataforma, e estamos expandindo e crescendo tudo o que podemos, tanto em termos de funcionalidade como em distribuição ... povoando mais e mais nossa linha de produtos com o Symbian", disse ele.

O novo modelo usará o processador Cortex-A8, da ARM.

"Se você olhar as propriedades de gestão de energia que temos no ARM, ao menos hoje, estamos claramente melhor, milhas e milhas melhor, do que temos na arquitetura da Intel", afirmou Vanjoki.

Fonte: Reuters

Criptografia com MD5 no Java ME

27 agosto 2009 0 comentários

O MD5 (Message-Digest algorithm 5) é um algoritmo de hash de 128 bits unidirecional, muito utilizado por softwares com protocolo ponto-a-ponto, verificação de integridade e logins.
Os hashes MD5 de 128-bit (16-byte) são normalmente representados por uma sequência de 32 caracteres hexadecimais. O seguinte mostra uma string ASCII com 43-bytes e o hash correspondente:

MD5("The quick brown fox jumps over the lazy dog")
= 9e107d9d372bb6826bd81d3542a419d6


Vulnerabilidade

Como o MD5 faz apenas uma passagem sobre os dados, se dois prefixos com o mesmo hash forem construídos, um sufixo comum pode ser adicionado a ambos para tornar uma colisão mais provável. Deste modo é possível que duas strings diferentes produzam o mesmo hash.

Vale ressaltar que o MD5 é um algoritmo de mão única! Então se gravarmos dados criptografados no banco (ex. Login/Senha), para fazermos a autenticação é necessário criptografar a string de entrada e comparar com o dado criptografado que está gravado no BD.

Neste post vamos mostrar um exemplo utilizando o algoritmo MD5 para criptografar uma senha afim de gravá-la no banco de dados. Essa técnica pode ser usada para qualquer tipo (ou toda) de informação que trafega pela rede ou que são gravadas no banco.

O MD5 é uma das soluções para criptografar informações, porém esta criptografia já é falha! Hoje já existem procedimentos que quebram este algoritmo, justamente por possuir uma Vulnerabilidade (citada acima).

Uma outra solução é um novo projeto Open Source brasileiro em Java, chamado BR1E.

Então vamos ao código para exemplificar o MD5 no Java / Java ME.


import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import com.twmacinta.util.MD5;

public class MD5Hash extends MIDlet implements CommandListener {

private Display display;
private Form FormTeste;
private TextField textField1;
private TextField textField2;
private Command comandoDeSaida;
private Command comandoCriptografar;

public void startApp() {
display.setCurrent(FormTeste);
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
display.setCurrent(null);
notifyDestroyed();
}

public MD5Hash() {
display = Display.getDisplay(this);
textField1 = new TextField("Senha", null, 120, TextField.ANY);
textField2 = new TextField("Senha Criptografada", null, 120, TextField.ANY);
FormTeste = new Form("Formulário");
FormTeste.append(textField1);

comandoDeSaida = new Command("Sair", Command.EXIT,1);
comandoCriptografar = new Command("Criptografar", Command.OK,1);
FormTeste.addCommand(comandoCriptografar);
FormTeste.addCommand(comandoDeSaida);
FormTeste.setCommandListener(this);
}

public void commandAction(Command comando, Displayable s)
{
if (comando == comandoDeSaida){
destroyApp(false);
}
if (comando == comandoCriptografar){
Criptografar();
}

}

public void Criptografar() {
FormTeste.append(textField2);

//converter o texto em bytes
byte plain[] = textField1.getString().getBytes();
// criar um objeto MD5Hash passando a sequencia de bytes resultante do texto digitado
MD5 md5 = new MD5(plain);
// pegando o resultado hash gerado
byte[] result = md5.doFinal();
// convertendo o conjunto de bytes em hexadecimal e aplicando ao objeto texto do display
textField2.setString(MD5.toHex(result));
}
}
Fonte:
http://pt.wikipedia.org/wiki/MD5
http://mobilepit.com/10/compact-md5-class-library-for-j2me-javame-app.html
http://www.devmedia.com.br/articles/viewcomp.asp?comp=6290&hl=

Transições de tela no LWUIT

20 agosto 2009 0 comentários

Hoje vamos aprender como fazer aqueles tão atraentes efeitos de transição de tela.

A transição pode ser Out ou In. No modo Out a transição é aplicada na saída do form. E no modo In o efeito de transição é aplicado quando o form está entrando, ou seja sendo mostrado na tela.

Tipos de Transições

Transições Comuns
  • Fade: a próxima tela surge de forma transparente sobrepondo a tela anterior.
 NOMEDOFORM.setTransitionOutAnimator(CommonTransitions.createFade(TEMPO));
TEMPO: Tempo de duração da transição, em milissegundos

  • Slide: transição estilo de slide. A próxima tela surge pela vertical ou
horizontal.
 NOMEDOFORM.setTransitionOutAnimator(CommonTransitions.createSlide(TIPO, BOOLEAN, TEMPO));
TIPO:
- CommonTransitions.SLIDE_HORIZONTAL
- CommonTransitions.SLIDE_VERTICAL
BOOLEAN:
- true: a tela vem da esquerda para a direita ou de cima para baixo
- false: a tela vem da direita para a esquerda ou de baixo para cima

Transições 3D
  • Cube: a transição funciona como um cubo giratório
  NOMEDOFORM.setTransitionOutAnimator(Transition3D.createCube(TEMPO,BOOLEAN));
BOOLEAN:
- true: a tela gira da esquerda para a direita
- false: a tela gira da direita para a esquerda


  • Rotation: É realizada uma rotação em torno do eixo central da tela
 NOMEDOFORM.setTransitionOutAnimator(Transition3D.createRotation(TEMPO, BOOLEAN));
BOOLEAN:
- true: a tela gira da direita para a esquerda
- false: a tela gira da esquerda para a direita


  • FlyIn: A nova tela surge do centro e cresce até preencher todo o espaço.
 NOMEDOFORM.setTransitionOutAnimator(Transition3D.createFlyIn(TEMPO));


  • SwingIn: A próxima tela surge como uma janela balançando.
  NOMEDOFORM.setTransitionOutAnimator(Transition3D.createSwingIn(TEMPO));
ou
  NOMEDOFORM.setTransitionOutAnimator(Transition3D.createSwingIn(TEMPO, BOOLEAN));
BOOLEAN:
-true: a tela está presa em cima e balança em baixo
- false: a tela está presa em baixo e balança em cima


Veja um aplicação de exemplo
import com.sun.lwuit.Command;
import com.sun.lwuit.Display;
import com.sun.lwuit.Form;
import com.sun.lwuit.animations.CommonTransitions;
import com.sun.lwuit.animations.Transition3D;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.plaf.UIManager;
import com.sun.lwuit.util.Resources;
import java.io.IOException;

import javax.microedition.midlet.*;

public class midletPrincipal extends MIDlet implements ActionListener{
Command troca, voltar;
Form fPrincipal;
Form fSecundario;

public void startApp() {
Display.init(this);
// TEMA
try{
Resources res = Resources.open("/imagens/javaTheme.res");
UIManager.getInstance().setThemeProps(res.getTheme(res.getThemeResourceNames()[0]));
}catch(IOException e){
}

fPrincipal = new Form("Transicoes");
fPrincipal.setTransitionOutAnimator(Transition3D.createCube(500, false));

troca = new Command("Trocar Tela");
fPrincipal.setCommandListener(this);
fPrincipal.addCommand(troca);
fPrincipal.show();
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

public void actionPerformed(ActionEvent e) {
if(e.getSource() == troca){
fSecundario = new Form();
voltar = new Command("Voltar");
fSecundario.addCommand(voltar);
fSecundario.setCommandListener(this);
fSecundario.setTransitionOutAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, false, 500));
fSecundario.show();
}
if(e.getSource() == voltar){
fPrincipal.show();
}
}
}
Para baixar o projeto completo clique aqui.

Brasil atinge 161 milhões de linhas móveis

19 agosto 2009 0 comentários

Segundo Alberto Alerigi (Reuters), o número de linhas celulares ativas em julho no Brasil cresceu 1,45 por cento ante junho, superando a barreira dos 160 milhões, segundo dados divulgados pela Agência Nacional de Telecomunicações (Anatel), nesta quarta-feira.

O país encerrou o mês passado com 161,922 milhões de linhas móveis, o que equivale a quase um celular por habitante (IBGE). Ante os 135,33 milhões de celulares de julho de 2008, a base avançou 19,64 por cento.

Segundo a agência, três Estados rompem a barreira de um celular por habitante: Rio de Janeiro, Mato Grosso do Sul (quem diria!) e São Paulo. Até então, o Distrito Federal era o único nessa categoria.

A Vivo, maior operadora móvel do país e controlada por Telefônica e Portugal Telecom, registrou ligeiro avanço sobre junho, encerrando o mês passado com 29,38 por cento de participação, equivalente a 47,565 milhões de linhas. Em junho, a empresa teve fatia de 29,33 por cento.

Enquanto isso, a Claro, da mexicana América Móvil e segunda colocada, teve leve recuo, de 25,36 por cento para 25,35 por cento, com 41,054 milhões de clientes.

A TIM, da Telecom Italia, fechou o mês passado com fatia de 23,75 por cento contra 23,71 por cento em junho.

A Oi, incluindo a Brasil Telecom, saiu de 21,22 por cento em junho para 21,15 por cento em julho.

Segundo a Anatel, de janeiro a julho foram adicionadas 11,28 milhões de linhas à base celular do país ante 14,35 milhões um ano antes.

Fonte: Reuters