quarta-feira, 21 de outubro de 2015

Como pegar a localização atual no Android?

Hoje precisei fazer uma app que usava a localização atual, é muito simples!

O projeto inteiro está aqui: https://github.com/adrianoschmidt/android-location-sample

Mas o segredo está nesta classe: MainActivity.java

Basicamente você tem q seguir esses 6 passos:

1) Sua Activity deve implementar as classes GoogleApiClient.ConnectionCallbacks e GoogleApiClient.OnConnectionFailedListener

    public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

2) Criar um atributo do tipo GoogleApiClient

    private GoogleApiClient googleApiClient;

3) No onCreate ou na chamada de um botão você deve verificar se está tudo certo com a API que pega a localização e se estiver construir a API e se conectar nela.

        if (this.checkIfGooglePlayServicesAreAvailable()) {
            this.buildGoogleApiClient();
            this.mGoogleApiClient.connect();
        }

Verificando:

    private boolean checkIfGooglePlayServicesAreAvailable() {
        int errorCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (errorCode != ConnectionResult.SUCCESS) {
            System.out.println("GooglePlayServices errorCode: " + errorCode);
            GooglePlayServicesUtil.getErrorDialog(errorCode, this, 0).show();
            return false;
        }
        return true;
    }


4) Implementar o método onConnected e pegar a localicação (aqui no exemplo seto em dois TextViews que tenho na minha tela)

    @Override
    public void onConnected(Bundle bundle) {
        TextView textViewLatitude = (TextView) findViewById(R.id.textViewLatitude);
        TextView textViewLongitude = (TextView) findViewById(R.id.textViewLongitude);

        Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
        if (mLastLocation != null) {
            textViewLatitude.setText("Lat: " + String.valueOf(mLastLocation.getLatitude()));
            textViewLongitude.setText("Lng: " + String.valueOf(mLastLocation.getLongitude()));
        }
    }

5) Implementar os métodos de suspensão e de falha:

    @Override
    public void onConnectionSuspended(int i) {
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
    }

6) Solicitar a permissão no manifest

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

Basicamente é isso, qualquer coisa baixe o projeto no github ou comenta aqui no post.

Abraço!
Adriano Schmidt

quinta-feira, 15 de outubro de 2015

count com distinct

Opa..

Se eu faço uma query com distinct:

SELECT distinct o FROM tabela1 o JOIN tabela2

Quando eu faço count dela não vai bater:

SELECT distinct count (o) FROM tabela1 o JOIN tabela2

Pra resolver posso fazer assim:

SELECT count (distinct o) FROM tabela1 o JOIN tabela2

Obrigado ao meu chará Adriano de Souza pela dica!

Abraço!
Adriano Schmidt

Atalhos IntelliJ

Opa :)

Eu uso o Eclipse desde sempre... então quando fui usar o IntelliJ IDEA para desenvolver para Android (Android Studio) eu me perdia nos atalhos... então fiz essa tabelinha com os principais atalhos para não me perder :D

O quê 
Eclipse 
IntelliJ 
Deleta a linha 
Ctrl+D 
Ctrl+Y 
Procura por arquivo 
Ctrl+shift+R 
Ctrl+shift+N 
Troca linha de lugar 
Shift+Up/Down 
Alt+shift+Up/Down 
Duplica a linha 
Ctrl+shift+Down 
Ctrl+D 
Navegar entre abas 
Ctrl+PgUp/PgDn 
Alt+Left/Right 
Organizeimports 
Ctrl+Shift+O 
Ctrl+alt+O 
Format 
Ctrl+sfhit+F 
Ctrl+alt+L 

Tem algum atalho que você acha que devia estar nessa lista? Comenta aí :)

Abraço!!
Adriano Schmidt

segunda-feira, 12 de outubro de 2015

Executar comandos linux no Android

Fala galera, precisei executar comandos linux pela minha app Android, para isso usei o código abaixo.

Troque o "date" que é o comando para pegar a data da máquina pelo comando que você quer executar.

No final deste exemplo, peguei o valor retornado e o mostrei em um TextView.

        try {
            String commandLine = "date";
            Process process = Runtime.getRuntime().exec(commandLine);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String value = bufferedReader.readLine();

            TextView dateTextView = (TextView) findViewById(R.id.text_info_line_6);
            dateTextView.setText(value);
        } catch (IOException e) {
            e.printStackTrace();
        }

No GitHub: https://gist.github.com/adrianoschmidt/8c83f972c20358a098a4

Caso você não queira fazer isso programaticamente pode usar o ADB Shell https://developer.android.com/tools/help/shell.html
É bem simples, basta acessar o terminal e ir até a pasta plataform-tools dentro da pasta do SDK do Android "cd <sdk_folder>\platform-tools"
Digite "adb devices" e tendo um dispositivo na lista basta digitar "adb shell" e você já pode digitar os comandos linux.

Vaaleu!
Adriano Schmidt

domingo, 11 de outubro de 2015

Android NDK - Hello World

O NDK é o Native Devolpment Kit e permite você escrever para android usando código nativo através de C ou C++

Geralmente se faz isso para obter mais performance (como é necessário no desenvolvimento de jogos por exemplo)

Mais detalhes em: https://developer.android.com/ndk/index.html

Eu estou usando para ver se consigo acessar recursos de telefonia para fazer uma conference... Mas enfim, segue um Hello World:

Faça o download do NDK: https://developer.android.com/ndk/downloads/index.html

Crie um novo projeto normalmente (File > New > New Project > dê um nome/domínio > Next > Next > Blank/Empty Activity > Finish)

No arquivo local.properties adicione uma linha com o caminho do seu NDK:

        ndk.dir=C\:\\android\\ndk\\android-ndk-r10e

No arquivo gradle.properties adicione isso:
android.useDeprecatedNdk=true

No arquivo build.gradle (da app) adicione em defaultConfig isso:

        ndk {
            moduleName "MyLib"
        }

Verifique se a MainActivity está estendendo diretamente a classe Activity, se não estiver, ajuste.

Na sua activity crie um método assim:
public native String getStringFromNative();

Vá em Build > Make

Depois vá no Terminal do Android Visual Studio e rode esse comando:

cd app\src\main

Depois rode esse comando (Não esquece de trocar as partes em negrito):

javah -d jni -classpath C:\android\sdk\platforms\android-23\android.jar;..\..\build\intermediates\classes\
debug br.com.localhost8080.ndksample.MainActivity

Isso vai criar uma pasta chamada jni com um arquivo .h nela

Crie nessa pasta jni um arquivo chamado main.c com o conteúdo abaixo (não esqueça de trocar os br_com_localhost8080_ndksample_MainActivity)

#include "br_com_localhost8080_ndksample_MainActivity.h"

JNIEXPORT jstring JNICALL Java_br_com_localhost8080_ndksample_MainActivity_getStringFromNative
        (JNIEnv * env, jobject obj)
  {
    return (*env)->NewStringUTF(env, "Hello from JNI!");
  }

Cria na mesma pasta um arquivo vazio chamado util.c (isso é necessário pois sem ele dá bug no gradle)

Depois dê um Build > Make

No activity_main.xml adicione um id no TextView:

android:id="@+id/my_textview"

Coloque na sua Activity

    static {
        System.loadLibrary("MyLib");
    }

No final do onCreate coloque:

        TextView tv = (TextView) findViewById(R.id.my_textview);
        tv.setText(getStringFromNative());

Dê um play e veja seu lindo HelloWorld escrito em C



Fontes no meu github: https://github.com/adrianoschmidt/ndk-sample

Para fazer esse hello world eu segui esse vídeo-tutorial (eh um pouco antigo, então peguei uns bugs que não apareceram no vídeo, e está em inglês): https://software.intel.com/en-us/videos/using-the-ndk-with-android-studio

Abraço!
Adriano Schmidt

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