domingo, 11 de outubro de 2015

Permissions no Android

Pessoal, hoje, na minha app Android, eu estava tentando fazer uma ligação. Dessa forma:

    private void callPhone() {
        Intent intent = new Intent(Intent.ACTION_CALL);
        intent.setData(Uri.parse("tel:456"));
        startActivity(intent);
    }


Mas deu o erro:

Caused by: java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.CALL dat=tel:xxx cmp=com.android.server.telecom/.components.UserCallActivity } from ProcessRecord{3e464e1 3861:br.com.localhost8080.myapp/u0a62} (pid=3861, uid=10062) requires android.permission.CALL_PHONE

Então fui no AndroidManifest.xml e coloquei a permission:

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


Mas aí aconteceu o erro:

Caused by: java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.CALL dat=tel:xxx cmp=com.android.server.telecom/.components.UserCallActivity } from ProcessRecord{ea870e6 4476:br.com.localhost8080.myapp/u0a62} (pid=4476, uid=10062) with revoked permission android.permission.CALL_PHONE

Para resolver usei o código abaixo pois a permission CALL_PHONE é level dangerous e você precisa solicitar permissao para o usuário:

    private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 1;

    public void onClick(View view) {
        int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE);
        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE);
        } else {
            callPhone();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_CALL_PHONE: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    callPhone();
                }
            }
        }
    }

    private void callPhone() {
        Intent intent = new Intent(Intent.ACTION_CALL);
        intent.setData(Uri.parse("tel:456"));
        startActivity(intent);
    }

Mais detalhes sobre permissões no android: https://developer.android.com/training/permissions/index.html

Mais detalhes sobre esse processo de ter que solicitar permissões: https://developer.android.com/training/permissions/requesting.html

sexta-feira, 9 de outubro de 2015

InfoQ - WildFly Avançado

Fala galera... esse ano palestrei no TDC Floripa sobre WildFly... mostrei um ambiente com cluster.. load balancer... entre outras coisas...

Essa semana o vídeo foi publicado na InfoQ, quem quiser dar uma olhadinha tá aí: www.infoq.com/br/presentations/wildfly-avancado




Obrigado a todos do JBug Brasil!!

Abraço!
Adriano Schmidt

quarta-feira, 7 de outubro de 2015

Map e Reduce em JavaScript

Para quem é do mundo JavaScript isso que vou mostrar é básico, mas quem é programador Java e precisou fazer isso em JavaScript com certeza tentou fazer um for... Vamos lá:

----------------

Imagine que você tenha uma lista de objetos... e cada objeto tenha um atributo chamado id... como você faria para obter uma nova lista com apenas com os ids?

Assim:

var idList = list.map(function(entity) {
    return entity.id;
});

----------------

Imagine que você tenha uma lista de objetos... e cada objeto tenha um atributo chamado value... como você faria para obter a soma de todos os atributos value?

Assim:

var valueTotal = list.reduce(function(valueTotal, entity) {
    return valueTotal + entity.value;
}, 0);

----------------

ATUALIZADO: FILTER

Imagine que você tenha uma lista de objetos, e queira que excluir dessa lista todos os itens com id < 10 (ou qualquer outra condição). Só usar o filter:

var filteredList = list.filter(function(entity) {
     return entity.id > 10;
});


----------------

Fontes no github: https://gist.github.com/adrianoschmidt/702dc06d9d7321600fb8

----------------

Vaaleu galera!
Adriano Schmidt

domingo, 27 de setembro de 2015

JavaScript no ServerSide com WildFly 10

Fala galera... fiz uns exemplos aqui pra testar a nova funcionalidade do WildFly 10 que permite que a gente escreva código JavaScript no Server Side \o) Criei alguns RESTs, um deles inclusive acessa um banco de dados e retorna o JSON....

Segue abaixo o código (github) e o passo-a-passo pra rodar aí na sua máquina.

Pré-requisitos:
- Java 8 instalado;
- Maven instalado;

Siga esses passos:
- Baixar e descompactar o WildFly 10
- Ir na pasta bin do WildFly e rodar o standalone.bat (no Windows) ou standalone.sh (no linux)
- Baixar esse projeto do github: https://github.com/adrianoschmidt/wildfly-js
- Abrir a pasta do projeto e rodar um "mvn clean install"
- Copiar o war gerado na pasta target do projeto e colar no <WildFly>/standalone/deployments
- Acessar via browser as seguintes URLs:

http://localhost:8080/wildfly-js/hello




http://localhost:8080/wildfly-js/hello/json




https://localhost:8080/wildfly-js/rest/members




Nesse post tem mais detalhes: http://wildfly.org/news/2015/08/10/Javascript-Support-In-Wildfly/

Abraço!!
Adriano Schmidt

Testar acesso JMX no WildFly

Fala pessoal,

Fiz uma classe Java para se comunicar com o JMX Client de um WildFly...

O fonte está no meu github:
https://github.com/adrianoschmidt/wildfly-jmx-client

Você pode usar isso caso precise mesmo acessar um JMX ou caso queira testar se ele está aberto ou não, esse foi meu caso. Em ambientes de produção é sempre interessante que ele não esteja visível.

Para usar a classe é só rodar ela normalmente pela IDE ou por linha de comando.

Repare nessas duas linhas:
String host = "localhost";
// String host = "192.168.0.35";

Com localhost, ao rodar na máquina onde está o WildFly deveria funcionar, pelo IP não deveria funcionar, pois por segurança não deveria estar disponível para acesso externo.

Para bloquear o acesso você pode fazer isso na sua infraestrutura ou no WildFly no stanalone.xml na seção interfaces.

Qualquer dúvida é só avisar!
Adriano Schmidt

terça-feira, 11 de agosto de 2015

JSON no Browser

Opa,

Se vc usa REST e ele retorna JSON... Instale essa extesion do chrome:

https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc?utm_source=chrome-app-launcher-info-dialog

Vai mudar suaa vida :D

Ela deixa formatadinho seu JSON... coisa linda!

Obrigado ao Guilherme Ribeiro pela dica!

Abraço!
Adriano Schmidt

domingo, 9 de agosto de 2015

node js - helloworld e um pouco mais

Semana passada comecei a brincar com Node JS.

Fiz um hello-world bem simples e rápido.

Caso queira fazer também, faça clone desse projeto e siga o arquivo README: https://github.com/adrianoschmidt/node-hello-world

Pronto, agora vamos um passo adiante.

No caso do Windows, depois vale à pena instalar mesmo o node (não só baixar o .exe e sim o .msi)

Agora instale o bower e o grunt
npm install -g bower
npm install -g grunt-cli

Baixe esse projeto e siga o README:
https://github.com/adrianoschmidt/seat-map-nodejs

Depois baixe o front-end desse seat-map (bootstrap, angular e grunt)
https://github.com/adrianoschmidt/seat-map-frontend

Qualquer dúvida é só comentar!

Abraço!
Adriano Schmidt

nome de arquivo muito longo no windows

Hoje tentei deletar uma pasta no Windows e aconteceu esse erro:

"Os nomes dos arquivos de origem são maiores do que o tamanho máximo permitido pelo sistema de arquivos."


Esse erro é causado pois o nome do caminho completo do arquivo é muito grande, mais do que o Windows suporta. No meu caso o npm criou umas pastas muito loucas no node_modules e aí gerou esse problema.

Para resolver faça o seguinte:

Alternativa 1) Renomear diretorios
Renomeie alguns diretorios, por exemplo:
Dê:
c:\work\projeto\node_modules\alguma coisa\outra coisa\diretorio com nome grande\mais uns 4 diretorios\arquivo.txt
Para:
c:\work\projeto\n\a\o\d\m\arquivo.txt

Assim o caminho do arquivo fica menor e tá tudo certo.

Alternativa 2) Mapear como unidade de rede

a) Faça uma pasta compartilhada
Você vai na pasta, talvez não na pasta mais interna, mas em alguma no meio do caminho e compartilha ela na rede (Botão direito na pasta > Compartilhar com)

b) Mapeie uma unidade de rede
Depois você tem que mapear essa pasta compartilhada como uma unidade de rede (Botão direito em Meu computador > Mapear unidade de rede > Escolhe a pasta compartilhada)

c) Exclua o arquivo
Ao acessar essa nova unidade (unidade "Z:" por exemplo) você vai conseguir excluir ou mover os arquivos pois agora o caminho completo do arquivo ficou menor.

-------------------

Qualquer dúvida é só comentar aí embaixo!!

Valeeu!!!
Adriano Schmidt

quinta-feira, 6 de agosto de 2015

Grunt com HTTPS/SSL em ambiente de desenvolvimento

Hoje precisei rodar o Grunt com HTTPS para fazer uns testes aqui. Segue o passo-a-passo:

Primeiro crie o certificado. Aqui estou usando o openssl no ubuntu. Se você usa Windows pesquise sobre como criar certificado no windows ( https://www.openssl.org/related/binaries.html )

openssl genrsa -out livereload.key 1024

openssl req -new -key livereload.key -out livereload.csr
(esse comando vai pedir alguns dados... vai preenchendo... Só em "Common Name" coloque "localhost" sem aspas)

openssl x509 -req -in livereload.csr -signkey livereload.key -out livereload.crt

Agora você tem 3 arquivos, copie os livereload.key e livereload.crt para dentro do seu projeto, na mesma pasta do Gruntfile por exemplo.
Eu criei uma pasta chamada ssl dentro da pasta onde está o Gruntfile.

----------------------

No seu Gruntfile no  "watch: {" você tem colocar esse options em todos os lugares que você quer que rode com https (no js, css e no livereload) por exemplo:

        options: {
            livereload: {
              port: 9000,
              key: grunt.file.read('ssl/livereload.key'),
              cert: grunt.file.read('ssl/livereload.crt')
            }
          }

Como ficou meu watch:

   watch: {
      bower: {
        files: ['bower.json'],
        tasks: ['wiredep']
      },
      js: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
        tasks: ['newer:jshint:all'],
        options: {
            livereload: {
              port: 9000,
              key: grunt.file.read('ssl/livereload.key'),
              cert: grunt.file.read('ssl/livereload.crt')
            }
          }
      },
      jsTest: {
        files: ['test/spec/{,*/}*.js'],
        tasks: ['newer:jshint:test', 'karma']
      },
      styles: {
        files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
        tasks: ['newer:copy:styles', 'autoprefixer'],
        options: {
            livereload: {
              port: 9000,
              key: grunt.file.read('ssl/livereload.key'),
              cert: grunt.file.read('ssl/livereload.crt')
            }
          }
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
     options: {
         livereload: {
           port: 9000,
           key: grunt.file.read('ssl/livereload.key'),
           cert: grunt.file.read('ssl/livereload.crt')
         }
       },
        files: [
          '<%= yeoman.app %>/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },


Agora no seu index.html, uma linha antes de fechar o body (</body>) cole isso:
<script>document.write('<script src="https://' + (location.host || 'localhost').split(':')[0] + ':9000/livereload.js"></' + 'script>')</script>

Pronto, ao rodar o "grunt serve --force" tudo estará rodando em HTTPS :)

Mais detalhes em: http://www.gilluminate.com/2014/06/10/livereload-ssl-https-grunt-watch/

Abraço! Qualquer dúvida comenta aí!
Adriano Schmidt

quarta-feira, 5 de agosto de 2015

X-Frame-Options to SAMEORIGIN

Eu estava fazendo um client OAUTH para fazer login via facebook e deu o erro:

Refused to display 'https://www.google.com.br/qualquerUrl' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.

Isso é problema de Same Origin Policy... uma política de segurança para evitar que scripts de um site acessem scripts de outro site. Mais em:
https://en.wikipedia.org/wiki/Same-origin_policy

Seguindo nessa linha instalei extensões no google chrome. Pesquisei por "cross domain" e achei várias. Mas não resolveu meu problema.

Iniciei o google chrome passando parâmetros para desabilitar a segurança. No Ubuntu fiz dessa forma:
google-chrome --disable-web-security --allow-file-access-from-files --allow-file-access --allow-cross-origin-auth-prompt
Mas não resolveu meu problema.

Achei que o erro estava acontecendo pois eu estava rodando em localhost ou 0.0.0.0 (estou usando grunt no meu projeto). Então tentei utilizar um DNS. Mas não resolveu meu problema.

Por fim, identifiquei, que minha empresa tinha um servidor de proxy, e por mais que minha máquina estivesse liberada e eu pudesse acessar tudo (pelo menos era o que parecia) verifiquei no network do chrome que o meu OAUTH Client acessava em algum momento a URL http://static.ak.facebook.com e o response vinha com uma página do google, e isso que gerava o erro.

Solução: Desligamos a máquina do proxy, não faz sentido hoje em dia usar isso :D E tudo funcionou perfeitamente \o)

Obrigado ao Herbert Smith e ao Alfredo Zipperer pela força!

Abraço!!!
Adriano Schmidt