Formatação NTFS e extFAT no pendrive de 2TB

Comprei um pendrive de 2TB no aplicativo do shopee.com por apenas R$25,00 e veio da China. Quando transferi os arquivos para ele fazendo um backup descobri que estava formatado em extFAT e alguns arquivos corrompiam e corrompia pastas tambem. Descobri que extFAT é para computadores 64x e o meu é 32x. Descobri tambem que o padrão de formatação NTFS tem auto-recuperador para falhas de desligamento. Formatei o pendrive no formato NTFS e os arquivos copiaram perfeitamente. Recomendo NTFS para pendrives de 2TB!

Agendando notificações de celular no Delphi mobile

O método PresentNotification usado até o momento, dispara uma notificação no exato momento que o botão é pressionado. Entretanto é possível agendarmos um alerta para outro horário ou data, por exemplo: podemos facilmente cria alerta que será disparado no futuro. Para isso usamos o método ScheduleNotification passando a ele a mesma variável. O único detalhe é que antes disso precisamos informar a notificação quando ela deverá ser disparada. E usamos a propriedade FireDate passando essa data e hora. Vejamos:

procedure TForm1.Button1Click(Sender: TObject);
var
Notificacao: TNotification;
begin
Notificacao := nctAlertas.CreateNotification;
try
Notificacao.Title := TreinaWeb;
Notificacao.AlertBody := Primeira Notificação;
Notificacao.FireDate := Now + EncodeDate(0, 0, 5, 0);
Notificacao.Number:=10;
nctAlertas.ScheduleNotification(Notificacao);
finally
Notificacao.DisposeOf;
end;
end;

Perceba que modificamos pouco do código que vimos no início dessa aula. Adicionamos somente a linha referente a alteração da propriedade FireDate a qual atribuímos a ela “Now + EncodeTime(0, 0, 5, 0)”. Essa expressão chama o método Now que retorna a data e hora atuais. Esse valor somamos com a expressão seguinte, EncodeTime. Essa função do Delphi cria uma nova hora baseada nos quatro parâmetros, Hora, Minuto, Segundo e Milissegundo. Em nosso exemplo estamos passando o valor 5 no parâmetro “Segundo”, ou seja, Data e Hora atuais mais cinco segundos. Nosso alerta será daqui 5 segundos a partir do momento que o botão é pressionado.

Criando notificação de celular no Delphi Mobile

Para que possamos trabalhar com notificações, devemos utilizar a classe TNotification, portanto é necessário criarmos uma variável desse tipo e instancia-la. Isso é necessário porque os métodos que chamaremos pedem como parâmetro uma variável do tipo TNotification. Vamos analisar como fazer a criação de uma única notificação em nosso aplicativo.

Crie um novo aplicativo no Delphi usando File > New > Multi-Device Application – Delphi e insira um controle do tipo TButton e um TNotificationCenter. No botão insira o nome “Primeira Notificação” sem as aspas na propriedade Text. Altere o nome do componente TNotificationCenter para nctAlertas e clique duas vezes sobre o botão para inserirmos um código em seu evento OnClick.

procedure TForm1.Button1Click(Sender: TObject);
var
Notificacao: TNotification;
begin
Notificacao := nctAlertas.CreateNotification;
try
Notificacao.Title := TreinaWeb;
Notificacao.AlertBody := Primeira Notificação;
nctAlertas.PresentNotification(Notificacao);
finally
Notificacao.DisposeOf;
end;
end;

O código anterior é bem simples e serve de base para operações de notificação. Veja, primeiro declaramos uma variável do tipo TNotification chamada Notificação. Na sequência nós instanciamos essa variável chamando o método CreateNotification presente no componente nctAlertas e passando atribuindo essa instância à nossa variável.

Notificacao := nctAlertas.CreateNotification;

Feito isso, nossa variável Notificacao está apta a ser configurada e ser usada para disparar uma notificação. Perceba que nas linhas seguintes nós atribuímos a palavra “TreinaWeb” à propriedade Title e o texto “Primeira Notificação” à propriedade AlertBody. A propriedade Title refere-se ao título da notificação, e AlertBody ao corpo dela.

Por fim nós chamamos o método PresentNotification passando como parâmetro a nossa variável. Isso faz com que o alerta seja disparado na mesma hora, criando por sua vez um ícone na parte superior do smartphone ou tablet. Ao passarmos o dedo sobre a notificação já no aparelho físico, o resultado que temos pode ser visto na figura a seguir.

Mostrando mapa com a localização no Delphi Mobile

O Delphi possui um componente chamado LocationSensor que interage com o sensor de localização presente em dispositivos móveis com Android e iOS. Isso é bom, pois é relativamente fácil detectarmos nossa posição no globo e apontar em um mapa usando algumas linhas de programação.

O LocationSensor pode ser encontrado na paleta de componentes Sensors no Delphi. Ele possui algumas propriedades e eventos que nos auxiliam em seu uso. A primeira propriedade dele, Accuracy, diz respeito a precisão em metros para que sejam disparados os eventos relacionados a captura de nossa localização. Em seguida temos a propriedade Active que informa se o componente está ativado ou desativado. Quando desativado, nenhum evento de captura de localização é disparado.

A terceira propriedade, Distance, diz respeito a distância mínima para capturar as posições de Latitude e Longitude. Em nosso exemplo, para que possamos mostrar em um mapa nossa posição atual, teremos que fazer uso de outro mecanismo, nesse caso do componente MapView presente no Delphi.

O MapView é responsável por mostrar um mapa do mundo em nosso celular. Quando usamos um LocationSensor, podemos enviar ao MapView nossas coordenadas e solicitar que o mapa centralize em nossa posição inclusive dando zoom no mapa.

O LocationSensor possui alguns eventos, ou seja, ações que podem ser capturadas e então programadas. O principal evento é o OnLocationChanged. Esse evento é capaz de analisar se mudamos nossa posição em relação ao mapa e então capturar a nova Latitude e Longitude. Em outras palavras, cada vez que andamos com nosso smartphone ou tablet em mãos, o LocationSensor captura a nova posição e ela é armazenada no componente nas variáveis Latitude e Longitude. O componente MapView precisa dessa Latitude e Longitude para nos mostrar no mapa. Algo como visto a seguir:

procedure TForm1.LocationSensor1LocationChanged(Sender: TObject;
const OldLocation, NewLocation: TLocationCoord2D);
var
MapCoord : TMapCoordinate;
MeuMarcador : TMapMarkerDescriptor;
FMarcadores : TList<TMapMarker>;
begin
MapCoord := TMapCoordinate.Create(NewLocation.Latitude,
NewLocation.Longitude);
MeuMarcador := TMapMarkerDescriptor.Create(MapCoord, Localização Atual);
MapView1.Zoom := 30;
FMarcadores.Add(MapView1.AddMarker(MeuMarcador));
end;

No exemplo anterior nós programamos o evento OnLocationSensor do componente LocationSensor de tal maneira que consigamos capturar a Latitude e Longitude do componente. Quem fornece essas informações é a variável NewLocation nos parâmetros do evento. NewLocation possui duas variáveis do tipo Double, dessa maneira apenas atribuímos o valor dessas duas variáveis ao método Create da variável MapCoord que criamos. Essa variável é responsável por receber as coordenadas e é usada posteriormente na classe TMapMarkerDescriptor para criarmos um marcador, ou um pino que será colocado dentro de nosso mapa.

Como podemos ver na sequência, nós adicionamos o marcador criado ao nosso MapView1. Com isso já é possível termos algo semelhante a figura a seguir:

Na figura anterior podemos ver o marcador vermelho ao centro do mapa. Essa é nossa posição no mapa sendo mostrada em um aparelho iPad. Como é possível ver, é bastante simples detectar as posições Latitude e Longitude através do Delphi com o componente LocationSensor e publicar um marcador em tela.

Lanterna no Delphi Mobile

Sabemos que é comum que smartphones e tablets Android e/ou iOS possuem câmera traseira para filmar e tirar fotos e que essas câmeras possuem flash. O flash desses dispositivos pode ser usado tanto para iluminar a cena na hora de tirar fotos quanto para usarmos como lanterna. Existem até alguns aplicativos que fazem outros usos do flash, como piscar ou acender sempre que recebemos uma ligação. Em nossa aula aprenderemos fazer uso do flash para criarmos a nossa própria lanterna.

A primeira providência que devemos tomar é baixar as imagens ilustrativas usadas em nosso aplicativo. Acesse o arquivo lanterna.zip. O arquivo possui a imagem de uma lanterna para colocarmos no formulário, bem como os botões liga desliga e uma imagem que represente a lanterna acesa. Precisaremos de imagens semelhantes as encontradas abaixo:

   

E nossa lanterna virtual se parecerá muito com o exemplo a seguir:

Estando de posse das imagens em formato .PNG, vamos criar uma nova aplicação utilizando o menu File > New > Multi-Device Application – Delphi. Salve o formulário com o nome UntLanterna.pas e o projeto como Laterna.dproj utilizando o menu File > Save All. No formulário adicione quatro componentes do tipo TImage. Acione a propriedade MultiResBitmap de cada um deles e individualmente selecione as imagens de nosso projeto utilizando o botão de carregamento de imagens.

Feito isso, alinhe os componentes TImage de forma que ser pareçam na prática com uma lanterna, como vimos nas imagens anteriores. As imagens referentes aos botões “liga/desliga”, procure coloca-las uma em cima da outra, pois nós faremos com que fiquem visíveis e invisíveis de acordo com o estado da lanterna, ou seja, ligada ou desligada. Não esqueça de dar nomes aos componentes do tipo TImage. Sugerimos os seguintes nomes:

  • imgLigar para a imagem com o botão ligar, em azul;
  • imgDesligar para a imagem com o botão desligar, em vermelho;
  • imgLuz para a imagem que simula a “lâmpada” da lanterna acesa;

Logo em seguida, adicione um componente chamado TCameraComponent. Esse controle nos dará completo acesso a câmera do smartphone/tablet e é por ele que conseguiremos adicionar o flash e ligar nossa lanterna. Modifique sua propriedade Name para “Camera” sem as aspas.

Veremos agora como criar um código-fonte capaz de ligar e desligar o flash da câmera simulando a nossa lanterna. A programação iniciará com a criação de um procedimento bastante simples que receberá o comando para ligar ou desligar. Abra o código-fonte de nosso aplicativo pressionando no teclado a tecla F12. Localize a cláusula Private no topo da janela de códigos. Adicione a ela o seguinte procedimento:

procedure LigarDesligarLanterna(Ativar: Boolean);

Pressione então Ctrl + Shift + C para que o Delphi crie para nós o escopo do nosso procedimento. Por fim, digite o código logo abaixo e vamos as explicações.

procedure TForm1.LigarDesligarLanterna(Ativar: Boolean);
begin
if Ativar then
begin
Camera.TorchMode := TTorchMode.ModeOn;
imgLigar.Visible := False;
imgDesligar.Visible := True;
imgLuz.Visible := True;
end
else
begin
Camera.TorchMode := TTorchMode.ModeOff;
imgLigar.Visible := True;
imgDesligar.Visible := False;
imgLuz.Visible := False;
end;
end;

A codificação é relativamente simples de ser entendida. No início de nosso código nós verificamos o conteúdo do parâmetro “Ativar” criado em nosso procedimento. Caso seja enviado como “True”, significa que queremos ligar a nossa lanterna, portanto acionamos o flash da câmera marcado “ModeOn” na propriedade “TorchMode” do componente câmera. Em seguida deixamos o TImage imgLigar invisível e o imgDesligar visível, assim teremos um botão vermelho em tela indicando que podemos desligar a lanterna. Por fim mostramos a imagem que simula a “lâmpada” da lanterna. Caso contrário, ou seja, enviarmos o parâmetro como “False” significa que queremos desligar a lanterna, então invertemos todo o processo. A propriedade TorchMode permanece “ModeOff” e deixamos os devidos controles visíveis ou invisíveis de acordo com a situação.

Sendo assim, acesse o evento OnClick do TImage referente ao botão para ligar a lanterna e faça a chamada ao procedimento que criamos. Como abaixo:

LigarDesligarLanterna(True);

Repita esse processo para o botão desligar, apenas invertendo o parâmetro para “False”. Em seguida vamos configurar os padrões de nosso aplicativo. Quando nosso aplicativo abrir a primeira vez, a lanterna estará desligada. Portanto deixe o componente referente ao “desligar” invisível. Faça isso marcado “False” na propriedade “Visible” dele. Faça o mesmo com a imagem referente a “lâmpada”, deixando-a invisível.

Nosso aplicativo ainda em tempo de projeto dentro do Delphi deverá se parecer com a imagem abaixo:

Experimente agora conectar seu smartphone ou tablet ao computador pela porta USB, compilar o projeto e executa-lo no aparelho. Veja que ao tocar no botão Ligar, o flash é automaticamente ligado e a imagem da lâmpada e do botão desligar é mostrado. Veja:

Rodando imagem e LongTap em Delphi Mobile

Vamos agora implementar o código para girarmos a imagem. Inicie criando uma variável com o nome FLastAngle, que sigifnica o último ângulo aplicado a nossa imagem. Ela pode ser adicionada juntamente com a variável FLastDistance criada anteriormente.

var
Form1 : TForm1;
FLastDistance: Integer;
FLastAngle : Double;

Por fim, abaixo do código referente ao zoom da imagem, adicione o algoritmo abaixo.

if EventInfo.GestureID = igiRotate then
begin
LObj := Self.ObjectAtPoint(ClientToScreen(EventInfo.Location));
if LObj is TImage then
begin
{ rotate the image }
LImage := TImage(LObj.GetObject);
if (TInteractiveGestureFlag.gfBegin in EventInfo.Flags) then
FLastAngle := LImage.RotationAngle
else if EventInfo.Angle <> 0 then
LImage.RotationAngle := FLastAngle (EventInfo.Angle * 180) / Pi;
end;
end;

Perceba novamente que estamos fazendo uso da constante EventInfo para descobrir qual o gesto praticado pelo usuário, mas desta vez nós estamos comparando-o a constante igiRotate. Caso seja detectado esse gesto, então mudamos o ângulo da imagem nas linhas posteriores.

Não se preocupe se não entendeu perfeitamente o código de ambas soluções, o que é mais importante aqui é saber detectar qual gesto está sendo praticado por quem usa nossa aplicação, ou seja, saber usar a constante EventInfo para isso.

Caso queira também implementar o toque longo, ou seja, o usuário pressiona o dedo e o segura por alguns segundos, isso é bastante fácil. Basta marcar a opção LongTap na sub-propriedade InteractiveGestures assim como foi feito para zoom e rotate. Em seguida acrescente o código abaixo também no evento OnGesture do formulário.

if EventInfo.GestureID = System.UITypes.igiLongTap then
ShowMessage(Você pressionou e segurou o dedo na imagem);

Mais uma vez fizemos uso da constante EventInfo comparada a outra constante igiLongTap para detectar o gesto do usuário. Experimente executar o exemplo do seu aparelho Android ou iOS e veja o resultado.

Dando Zoom em Imagem usando Delphi Mobile

A primeira coisa que devemos fazer é configurar o componente Gesture Manager para aceitar os gestos de zoom, rotação. Esse último servirá para que possamos girar a imagem. Em seguida insira um componente do tipo TImage no formulário. Marque sua propriedade Align com a opção Center. Por fim, clique duas vezes sobre a propriedade MultiResBitmap e escolha uma foto usando o botão Open à direita do campo referente ao caminho da imagem:

 

Vamos iniciar a codificação criando uma variável. Ela será responsável por guardar a última posição. Localize a cláusula var logo acima de Implementation e adicione as variáveis. Caso a cláusula var não exista, digite-a.

Var
Form1 : TForm1;
FLastDistance: Integer;

A variável guardará a última distância de zoom na imagem, assim o zoom será sempre incremental. Feito isso precisaremos codificar agora o evento OnGesture do formulário. Preencha como mostrado abaixo.

procedure TForm1.FormGesture(Sender: TObject;
const EventInfo: TGestureEventInfo; var Handled: Boolean);
var
LObj: IControl;
LImage: TImage;
LImageCenter: TPointF;
begin
if EventInfo.GestureID = igiZoom then
begin
LObj := Self.ObjectAtPoint(ClientToScreen(EventInfo.Location));
if LObj is TImage then
begin
if (not(TInteractiveGestureFlag.gfBegin in EventInfo.Flags)) and
(not(TInteractiveGestureFlag.gfEnd in EventInfo.Flags)) then
begin
{ zoom the image }
LImage := TImage(LObj.GetObject);
LImageCenter := LImage.Position.Point + PointF(LImage.Width / 2,
LImage.Height / 2);
LImage.Width := LImage.Width + (EventInfo.Distance FLastDistance);
LImage.Height := LImage.Height + (EventInfo.Distance FLastDistance);
LImage.Position.X := LImageCenter.X LImage.Width / 2;
LImage.Position.Y := LImageCenter.Y LImage.Height / 2;
end;
FLastDistance := EventInfo.Distance;
end;
end;
end;

Apesar de um código relativamente grande, ele é simples de ser entendido. A primeira linha abaixo do primeiro begin diz respeito a detecção do gesto praticado pelo usuário. Perceba:

if EventInfo.GestureID = igiZoom then

A constante EventInfo, presente nos parâmetros do evento, recebe o ID (Identificador) do gesto praticado através do método GestureID. Ele então é comparado a constante igiZoom. Se foram iguais então capturamos a foto dentro do TImage e alteramos algumas de suas propriedades para darmos o efeito de zoom. Perceba que alteramos seu posicionamento em Position, sua altura e largura em Height e Width, respectivamente, e por fim guardamos sua última distantância na variável FLastDistance.