Android aplikace + New Relic

Pro analýzu používání a padání Android aplikací se mi osvědčil New Relic (mimochodem, je super i na server). V základní verzi je zadarmo. Obsahuje základní informace které pro malé aplikace bohatě stačí (v kombinaci New relic + Google play API mi momentálně nechybí žádná funkčnost). Pro mne nejužitečnější je crash list report, kde vidíte všechny pády vaší aplikace včetně mnoha informací (jaké to bylo zařízení, verze Androidu , …), Je naivní si myslet, že když aplikace funguje na mém zařízení, bude fungovat všude… Vždy jsem matně vzpomínal jsem jsem New Relic do aplikace dostal. To co stačí udělat naleznete v tomto videu:

Ať slouží 🙂

Android: GPS souřadnice zařízení

V dnešním článku si ukážeme jak z Android zařízení získat aktuální GPS polohu. K získání polohy použijeme LocationListener.

Oprávnění pro přístup k poloze

Do AndroidManifest.xml přidáme následující oprvnění:

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

Používáme Android LocationManager

Activita ve které chceme zjistit GPS polohu musíme implementovat rozhraní LocationListener (z package android.location.LocationListener)

public class MainActivity extends Activity implements LocationListener {
    
    private LocationManager locationManager;

kde následně musíme přetížit tyto metody:

    @Override
    public void onLocationChanged(Location location) {
        Log.d("GPS", "Lat: " + location.getLatitude() + "Lon: " + location.getLongitude());
        Toast.makeText(getActivity(), "Lat: " + location.getLatitude() + "Lon: " + location.getLongitude(), Toast.LENGTH_LONG).show();
        locationManager.removeUpdates(this);//stop gps changes, only ONE
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {
        Toast.makeText(getActivity(), "Gps is turned ON", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onProviderDisabled(String provider) {
        Toast.makeText(getActivity(), "Gps is turned OFF", Toast.LENGTH_SHORT).show();
    }

Vynutíme získání polohy:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
 
   locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
   locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, this);
}

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 1, this) kde parametry funkce:

provider provider pro zjištění polohy
minTime minimální interval pro aktualizaci polohy (v milisekundách)
minDistance minimální vzdálenost mezi aktualizacemi (v metrech). Pokud nepotřebujeme změnu po metrech, nastavíme na 0 -> tím se bude aktualizovat pouze podle česového intervalu (minTime)
listener listener jehož metoda onLocationChanged(Location) se zavolá s každou změnou

Pokud budeme chtít listener pro zjišťování polohy ukončit, zavoláme:

locationManager.removeUpdates(this);

Všimněte si že první zjištění polohy trvá docela dlouho a zařízení se zahřívá více než obvykle. I baterie ubývá rychleji než obvykle 🙂 Příště si ukážeme šetrnější způsob jak zjišťovat polohu zařízení, který při prvním spuštění rychle vrátí naposledy známou polohu a poté ji zpřesní, nebo jak zjistit, že GPS je vypnuta.

Jak nainstalovat Bower pod Windows

Minule jsme si nainstalovali Grunt a vytvořili package.json

Nyní se rovnou pustíme do instalace Boweru. Bower nainstalujeme globálně abychom ho mohli použít kdekoliv:

npm install -g bower

Také Bower nainstalujeme lokálně aby se přidal do projektu (package.json)

npm install bower --save-dev

Inicializujeme Bower (vytvoří soubor bower.json):

bower init

 

Hledání balíčků

Existují 2 způsoby jak najít balíček pro Bower. Buď přes webový prohlížeč nebo přes příkazovou řádku.

Chcete li vyhledat balíček přes příkazovou řádku, použijte následující příkaz:

bower search <balicek>

Pro vyhledání balíčku obsahující slovo jQuery použijeme příkaz:

bower search jquery

Tento příkaz vrátí spoustu výsledků:

    jquery git://github.com/components/jquery.git
    jquery-ui git://github.com/components/jqueryui
    jquery.cookie git://github.com/carhartl/jquery-cookie.git
    jquery-placeholder git://github.com/mathiasbynens/jquery-placeholder.git
    jquery-file-upload git://github.com/blueimp/jQuery-File-Upload.git
    jasmine-jquery git://github.com/velesin/jasmine-jquery
    jquery.ui git://github.com/jquery/jquery-ui.git
    ...

Každý balíček odkazuje na Git repozitář.

Instalace Balíčků

bower install jquery#1.*.* --save-dev         //last version jquery 1.x.x
bower install nette-forms --save-dev
bower install bootstrap --save-dev
bower install bootstrap-sass-official --save-dev
bower install jquery-smooth-scroll --save-dev
bower install font-awesome --save-dev

Android: Začínáme s Volley

Knihovnu Volley vyvinula společností Google. Slouží pro rychlou a snadnou komunikaci přes internet v systému Android. Dnes si ukážeme jak Volley používám pro stahování dat z internetu. Především stahování dat z REST API.

Do knihovny Volley přispěl svým kódem můj kolega Zdeněk Kořán 🙂

Gradle v Android Studiu

Pro všechny mé projekty pro Android používám Android Studio. Je to ideální volba. Zprovoznění simulátoru a nainstalování SDK (oproti Eclipse) je velice jednoduché a příjemné.

Gradle je nástroj pro automatizaci. Slouží k: build, CI, deployment, generování dokumentace, … Po vytvoření nového projektu v Android Studio je Gradle výchozí nástroj.

Přidání Volley knihovny do projektu v Android Studiu

Vytvořte v Android Studio nový projekt. Otevřete soubor build.gradle do kterého doplníme závislost:

// /app/build.gradle
// ...

dependencies {
  // ...
  compile 'com.mcxiaoke.volley:library:1.0.+'
}

Lepší je načíst poslední verzi knihovny Volley: File -> Project Structure… -> app -> Dependencies -> Add -> Library dependency kde v modálním okně vyhledáme „com.mcxiaoke.volley:library“ kterou přidáte. Hotovo 🙂

Soubor build.gradle pak vypadá takto:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "cz.vencax.beerdroid.beerdroid"
        minSdkVersion 14
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.0.0'
    compile 'com.android.support:support-v4:22.0.0'
    compile 'com.mcxiaoke.volley:library:1.0.+'
}

Použití Volley knihovny

Volley knihovnu již máme naimportovanou. Pojďme ji začít používat k stahování obsahu z internetu. Kdybychom nepoužili Volley museli bychom obsah stahovat v samostatném vlákně přes AsyncTask. S Volley to je jednoduché. Volley pro požadavky ke stažení používá Request Queue. Pro globální frontu požadavků si vytvoříme statickou třídu VolleySingleton.

VolleySingleton.java:

import android.content.Context;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;

public class VolleySingleton {

    private static VolleySingleton mInstance;
    private RequestQueue mRequestQueue;
    private static Context mCtx;

    private VolleySingleton(Context context) {
        mCtx = context;
        mRequestQueue = getRequestQueue();
    }

    public synchronized static VolleySingleton getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new VolleySingleton(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }
}

Přidáme oprávnění pro přístup na internet (<uses-permission android:name=„android.permission.INTERNET“ />):

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cz.vencax.beerdroid.beerdroid" >

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

</manifest>

 Stažení JSONu přes Volley

Nyní máme vše připraveno a můžeme začít stahovat obsah z internetu přes Volley.

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> volley
        JsonObjectRequest request = new JsonObjectRequest("http://cblunt.github.io/blog-android-volley/response.json", null,
                new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_SHORT).show();
                    }
                },

                new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(getApplicationContext(), "EROOR: " + error.toString(), Toast.LENGTH_SHORT).show();
                    }
                }
        );

        VolleySingleton volleySingleton = VolleySingleton.getInstance(getApplicationContext());

        volleySingleton.getRequestQueue().add(request);
        // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< volley
    }

Jak sami vidíte, s knihovnou Volley je stahování zdrojů z internetu velice jednoduché a rychlé. Sám Google ji používá u svých služeb (Google Play, Youtube, …), nemusíte se tudíž bát že Vaši aplikaci zpomalí.

Mne tato knihovna ušetřila spousty vlasů na hlavě 🙂

Na co si dát pozor

U JSONu se rozlišují 2 typy. Pozor na to při requestu.

JSONObject

začíná znakem {

JSONArray

začíná znakem [

První projekt s Apache Wicket

Jeden z nejlepších webových frameworků pro programovací jazyk Java je Apache Wicket. V dnešním článku si ukážeme jak ho rozchodit na Windows.

Maven

Maven je mocný nástroj pro správu projektů. My ho použijeme pro Wicket Quickstart

  1. http://maven.apache.org/download.html
  2. Stáhnout apache-maven-3.3.1-bin.zip
  3. Stažený Maven rozbalíme do: C:\apache-maven-3.3.1
  4. Přidáme proměnné prostředí s názvem MAVEN_HOME s hodnotou C:\apache-maven-3.3.1
  5. Do proměnného prostředí s názvem Path přidáme (na úplný konce, nezapomeňte na středník!):
    ;C:\apache-maven-3.3.1\bin
  6. Restartujeme PC. Maven je nainstalován. Vyzkoušejte jeho správnou funkčnost: Start -> cmd
    mvn -version

    Zobrazí se verze nainstalovaného Mavenu

Instalace Eclipse

Eclipse je nástroj, který je zdarma a vřele ho doporučuji všem začátečníkům.

  1. http://www.eclipse.org/downloads/
  2. Stáhněte Eclipse IDE for Java EE Developers
  3. Stáhne se zip soubor, který stačí rozbalit a rovnou spustit eclipse.exe (neinstaluje se)

Vytvoření Wicket projektu

Na stránce: https://wicket.apache.org/start/quickstart.html naklikáme vlastnosti (můžeme nechat defaultní) a v cmd vykonáme Command line kód:

mvn archetype:generate -DarchetypeGroupId=org.apache.wicket -DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=6.19.0 -DgroupId=com.mycompany -DartifactId=myproject -DarchetypeRepository=https://repository.apache.org/ -DinteractiveMode=false

Kód vytvoří nový projekt ve složce myproject

Spuštění Wicket projektu v Eclipse

v příkazové řádce se dostaneme do projektu:

cd myproject

Nyní spusťte příkaz:

mvn eclipse:eclipse

Tím se vytvoří soubory: .project, .settings, a .classpath které vyžaduje Eclipse.

Nyní naimportujeme projekt do Eclipse. V menu vyberte: File->Import->General->Existing Project into Workspace

V levé části Eclipse najedeme na soubor: src/test/java kde nás zajímá soubor Start.java klikneme na něj pravým tlačítkem a vybereme: Debug as… -> Java Application. Ve spodní části eclipse je Console ve které můžete vidět spouštěná webového serveru.

Správnou funkčnost Wicketu otestujete zobrazením adresy: http://localhost:8080 na které vás vítá Apache Wicket

MySQL vzdálenost GPS souřadnic

Jak v MySQL spočítat vzdálenost mezi 2 body? Použijeme uloženou proceduru:

DROP FUNCTION IF EXISTS `gps_distance`;

DELIMITER $$
CREATE FUNCTION `gps_distance` (lat1 float, lng1 float, lat2 float, lng2 float) RETURNS float
BEGIN
 
    SET lat1 = lat1 * pi() / 180;
    SET lng1 = lng1 * pi() / 180;
    SET lat2 = lat2 * pi() / 180;
    SET lng2 = lng2 * pi() / 180;
 
    RETURN acos
    (   cos(lat1)*cos(lng1)*cos(lat2)*cos(lng2)
      + cos(lat1)*sin(lng1)*cos(lat2)*sin(lng2)
      + sin(lat1)*sin(lat2)
    ) * 6372.795;
 
END$$

DELIMITER ;

 

Jak v jQuery vytvořit jednoduchý doplněk

Dělám doplněk který zobrazuje Google mapu. Doplněk umožňuje zobrazit několik markerů na mapě, nebo zobrazit 1 marker kterým je možné uživatelsky vybrat pozici. Nyní bych potřeboval rozšířit tento doplněk o možnost zadání souřadnic markeru z venku doplňku.

Jak to nyní funguje

<div id="google-map">v tomto divu je zobrazena mapa na které je marker</div>

Úkolem je této mapě (map může být na stránce více) nastavit souřadnice markeru.

Vyřešení

Do JavaScriptu pro zobrazení mapy přidám následující kód:

$( document ).ready( function() {

  $.fn.setMarkerPosition = function(lon, lat){
    $(this).css("border", "pink solid 10px");//at je to videt :-)
    alert("lon: " + lon + ", lat: " + lat );
    return this;
  };
  //...

Nyní stačí zavolat námi vytvořenou funkci setMarkerPosition()

$( "div#nette-g-map-canvas" ).setMarkerPosition( 1.1111, 2.2222 );

 

Google Analytics: Změna URL

Dost často se setkávám se stránkami které mají veškerý svůj obsah na jedné dlouhé stránce. Stránka je rozdělena na sekce a při zobrazení sekce se změní URL adresa (většinou se změní hashtag: #kontakt, #nabidka, #kontaktni-formular, … )

Pokud na tokovou stránku nasadíte Google Analytics, měření nebude dávat smysl (uvidíte statistiky pouze pro jednu stránku). Nebudete vědět jaké sekce uživatele zajímají, na jaké sekce přicházejí, z jakých sekcí odcházejí,….

Tento problém jsem vyřešil zajímavým způsobem. Pokud dojde ke změně URL (změní se hashtag), pošlu do Google Analytics zprávu o tom kde se nachází uživatel:

var page = location.pathname + "#"+ hashtag;
ga( 'send', 'pageview', page );

Kde location.pathname je cesta aktuální URL.

 

Breadcrumbs – drobečková navigace

Co je to breadcrumbs?

Breadcrumbs neboli drobečková navigace je sada odkazů které mohou uživateli pomoci pochopit a procházet hierarchii stránek. Příklad:

Webmaster ToolsHelp articlesMy site and GoogleCreating Google-friendly sites

Přidáte-li breaderumbs navigaci na Vaše stránky pomůžete vyhledávačům pochopit navigaci na stránkách a vyhledávače tuto informaci začnou prezentovat při vyhledávání:

breadcrumbs

 Ukázka použití

<div itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
  <a href="http://www.example.com/knihy" itemprop="url">
    <span itemprop="title">Knihy</span>
  </a> ›
  <div itemprop="child" itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
    <a href="http://www.example.com/knihy/autori" itemprop="url">
      <span itemprop="title">Autoři</span>
    </a> ›
    <div itemprop="child" itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
      <a href="http://www.example.com/knihy/autori/bozena-nemcova" itemprop="url">
        <span itemprop="title">Božena Němcona</span>
      </a>
    </div>
  </div>
</div>

 Ověření správné funkčnosti

Správnost konfigurace drobečkové navigace můžete ověřit na adrese: https://developers.google.com/structured-data/testing-tool/