Honneywell Dolphin 75e

Do práce jsme vybírali mobilní terminál, který bude mít hardwarovou čtečku čárových kódu. Po prozkoumání nabízených zařízení nám zůstaly pouze zařízení s OS Android (snad s tím W10 ještě zahejbe ale asi to potrvá). Nakonec jsme vybrali Honneywell Dolphin 75e ale pro ten nefungují oficiální ovladače. WTF?

Nakonec jsem to obešel takto a ovladače fungují:

  1. přesvědčte se že máte nainstalovány ovladače pro Google USB Driver
    doolphin75e_1
  2. Úprava android_winusb.inf
    Soubor android_winusb.inf jsem v mém případě nalezl na: C:\Users\pc-x\AppData\Local\Android\sdk\extras\google\usb_driver\android_winusb.infProvedeme jeho editaci a za sekce Under both the [Google.NTx86] [Google.NTamd64] přidáme:

    ;Honeywell Dolphin Android Product[A0:fastboot,A1:adb,A2:UMS,A3:ums-adb]
    %SingleAdbInterface% = USB_Install, USB\VID_0C2E&PID_0BA0&MI_00
    %SingleAdbInterface% = USB_Install, USB\VID_0C2E&PID_0BA1
    %CompositeAdbInterface% = USB_Install, USB\VID_0C2E&PID_0BA3&MI_01
    %SingleBootLoaderInterface% = USB_Install, USB\VID_0C2E&PID_0BA0
    
  3. Ve Správci zařízení zvolíme na neznámém zařízení Aktualizace software ovladače… a vybereme Vyhledat ovladač v počítači kde zvolíme cestu:
    C:\Users\pc-x\AppData\Local\Android\sdk\extras\google\usb_driver

    vyskočí upozornění, že Windows nemůže oveřit vydavatele tohoto software, to potvrdíme a ovladače máme nainstalované 🙂

ADB

Nyní když máme ovladače, můžeme použít adb příkazy.

adb shell
adb devices

 

Mikrotik – aktualizace firmware

Jak se připojit do Mikrotiku

Máme několik možností jak se do Mikrotiku přihlásit (seriová linka, telnet, SSH, webové rozhraní, …) My si dnes ukážeme přihlášení přes Winbox.

Stáhneme Winbox – jedná se o .exe soubor, který se neinstaluje – pouze se spustí.

Winbox po spuštění vypadá takto:

mikrotik-1

Automaticky dojde k vyhledání všech Mikrotiků na síti a zobrazení základních informací. Dvojklikem vybereme Mikrotik do kterého se chceme přihlásit, tím se načte do horní části okna. Zadáme login a heslo. Kliknutím na tlačítko Connect proběhne připojení.

Defaultní nastavení přístupových údajů pro Mikrotik v továrním nastavení:

login: admin
password: je prázdné

Základy práce s Winboxem

Po úspěšném připojení do Mikrotiku se otevře následující okno:

mikrotik-2

Všimněte si záhlaví okna, kde jsou důležité informace:

Vidíme na jakého uživatele a na jakém Mikrotiku jsme připojeni: admin@192.168.88.1
Název Mikrotiku: rozostřeno
Aktuální verzi RouterOS: 5.2.4
A typ zařízení: RB532 (mipsle)

Pokud chceme aktualizovat firmware, musíme stáhnou správný RouterOS pro náš typ.

Stažení RouterOS

Již víme jaké zařízení máme ( RB532 (mipsle) ), můžeme se poohlédnou po RouterOS.Jak jinak než na oficiálních stránkách Mikrotiku kde je sekce Download.

mikrotik-4

Vybereme požadovanou verzi. Aktuálně je poslení verze 6.33. Nyní je potřeba dávat pozor, jelikož sekce mipsle je v seznamu 2x a musíte správně vybrat podle vašeho typu Mikrotiku! Do PC stáhneme Main package (cca 12MB).

Záloha Mikrotiku přes Winbox

Před aktualizací si udělejte zálohu stávajícího nastavení. V menu vybereme Files a klikneme na tlačítko Backup.

mikrotik-5

Vznikne nový soubor, který přes schránku (nahoře v okně Files je ikona Copy) zkopírujeme do PC.

Aktualizace firmware na Mikrotiku přes Winbox

Nyní můžeme nainstalovat stažený Main package balíček. V mém případě má balíček takovýto název: routeros-mipsle-6.33.npk

Tento soubor nahrajeme do sekce Files (přetažením do otevřeného okna Files). Následně v menu vybereme System -> Reboot a Mikrotik si automaticky nahraje tento nový firmware.

Window 7: jak smazat instalaci Windows 10 a nabídku na upgrade

Pokud neplánujete upgrade na Windows 10 a dochází vám volné místo na disku, máte možnost smazat staženou instalaci Windows 10. Instalace Windows 10 se stáhnou do PC bez vědomí uživatele a my si ukážeme jak se instalace zbavit. Stažená instalace má přibližně 6GB, tak proč se jí nezbavit když neplánujete upgrade?

Jak smazat staženou instalaci Windows 10

Pokud již máte staženou instalaci Windows 10 ve svém počítači (otravuje vás upgrade na Windows 10), jděte na Tento počítač -> disk C na který klikneme pravým tlačítkem a vybereme vlastnosti. Na první záložce s názvem Obecné klikneme na tlačítko Vyčištění disku. Jsou nám nabídnuty soubory které je možné smazat. Na tomto místě máte první možnost jak udělat volné místo na disku. Pro smazání W10 je nutné kliknout na tlačítko Vyčistit systémové soubory

w10-1

Zobrazí se nám další okno kde hledejte položku Dočasné instalační soubory systému Windows. Pokud potvrdíte, počítač bude chvíli chroupat a posléze je místo uvolněno 🙂

 

w10-2

Odstranění nabídky na upgrade Windows 10

w10-3

Spustíme Ovládací panely -> Windows Update

w10-4

Klikneme na Zobrazit historii aktualizací a poté Nainstalované aktualizace

w10-5

Odinstalujeme aktualizaci KB3035583 a restartujeme PC

w10-6

Už máme skoro hotovo 🙂 Nyní musíme aktualizaci KB3035583 skrýt aby se již příště nenainstalovala. V Ovládací panely -> Windows Update dáme Vyhledat aktualizace

Mezi důležitými aktualizacemi naleznete naši oblíbenou KB3035583 🙂 Klikněte na ni pravým tlačítkem a zvolte Skrýt aktualizaci

Další (jednodušší) způsob je použít program GWX Control Panel

Android jak na služby (services)

Pokud v Androidu vykonáváte větší množství operací, není vhodné tuto práci dělat v hlavním vlákně aplikace. Tuto práci musíte udělat v novém vlákně (AsynsTask) nebo ve službě (services). Dnes si ukážeme jak udělat jednoduchou službu.

Na rozdíl od aktivit běží služby na pozadí a nepotřebují uživatelské rozhraní. Služba běží paralelně s hlavním vláknem. Klasickým příkladem služby je přehrávač hudby na pozadí. Když hudba hraje, uživatel se může přepnout do jiné aplikace a přehrávání hudby se nepřeruší. Klasickým případem je stahování/odesílání dat z internetu, práce s databází, zpracování velkých souborů, přehrávání hudby,…

Služby je nutné registrovat v AndroidManifest.xml

    <application ....>
        <activity android:name=".activity.MainActivity" >
           ...
        </activity>

        <service
            android:name=".service.MyService"
            android:exported="false" >
        </service>

    </application>

Poslední dobou se mi líbí přístup definování volání služby jako statickou metodu přímo v service:

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import my.namespace.Config;

public class MyService extends IntentService {

    private static final String MY_TASK = "my.namespace.action.MY_TASK";
    private static final String MY_PARAM = "myParam";


    public MyService() {
        super("MyService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        if (intent != null) {
            final String action = intent.getAction();
            String myParam = intent.getStringExtra(MY_PARAM);

            if (MY_TASK.equals(action)) {

                //my task hard work
                if (Config.DEBUG) Log.d(Config.TAG, "my task hard work with my param: " + myParam );

            }
        }
    }

    public static void runMyService(Context context, String parameter) {

        if (Config.DEBUG) Log.d(Config.TAG, "runMyService()");

        Intent intent = new Intent(context, MyService.class);
        intent.setAction(MY_TASK);
        intent.putExtra(MY_PARAM, parameter);
        context.startService(intent);

    }

}

Metodou runMyService spustíme službu, která vynutí zavolání metody onHandleIntent kde se podle proměnné action rozhodne jaká z úloh se bude provádět (v budoucnu se předpokládá více činnosti pro službu).

Zavolání služby je pak jednoduché:

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

        if (Config.DEBUG) Log.d(Config.TAG, "onCreate()");

        MyService.runMyService(getContext(), "muj parametr");

    }

 

 

WordPress – jak v PHP nastavit cron (wp_cron)

Dnes si ukážeme jak v pluginu pro WordPressu nastavit wp_cron. Cron je script (ve WP světě funkce) který se spustí vždy v požadovanou dobu.

Jediné případné použití je na hostingu, který nepodporuje cron, nebo má omezený počet úloh pro cron. Wp_cron totiž funguje tak, že když přijde návštěvník na web, podívá se zda uplynula doba na spuštění cron úlohy. Pokud doba uplynula spustí cron úlohu a poznamená si čas kdy tato úloha byla naposledy spuštěna aby věděl kdy ji spustit příště.

To je fajn ale má to několik nedostatků:

  • Pokud na Váš web za celý den nepřijde žádný člověk, nevykoná se cron pro hourly četnost ani jednou (normálně by se vykonal 24x)
  • Pokud máte cron úlohu, která se vykonává dlouho, návštěvník který tuto úlohu „spustil“ musí počkat než doběhne aby se mu zobrazila požadovaná stránka

Raději doporučuji spouštět kód klasickým cronem.

Ukázka nejjednoduššího cronu, který se vykoná každou hodinu – odesílá email:

if ( ! wp_next_scheduled( 'my_task_hook' ) ) {
  wp_schedule_event( time(), 'hourly', 'my_task_hook' );
}

add_action( 'my_task_hook', 'my_task_function' );

function my_task_function() {
  wp_mail( 'your@email.com', 'Automatic email', 'Automatic scheduled email from WordPress.');
}

Cron pro WordPress plugin

U pluginu je nejrozumnější cron zapnout při aktivaci pluginu. Nezapomeňte cron opět odebrat při deaktivaci pluginu.

Jak zjistím, že plugin byl aktivován nebo deaktivován?

function activate_plugin_name() {
   //plugin byl aktivovan
}

function deactivate_plugin_name() {
   //plugin byl deaktivovan
}
register_activation_hook( __FILE__, 'activate_plugin_name' );
register_deactivation_hook( __FILE__, 'deactivate_plugin_name' );

Jednoduché, ale stálo mne to dost vlasů 🙂 Finální kód pro plugin:

/**
 * Tento kod se vykona pri aktivaci pluginu
 */
function activate_plugin_name() {
   if( !wp_next_scheduled( 'mycronjob' ) ) {
      wp_schedule_event( time(), 'hourly', 'mycronjob' );
   }
}
/**
 * Tento kod se vykona pri deaktivaci pluginu
 */
function deactivate_plugin_name() {
   wp_clear_scheduled_hook('mycronjob');
}
//hook pro aktivaci a deaktivaci pluginu
register_activation_hook( __FILE__, 'activate_plugin_name' );
register_deactivation_hook( __FILE__, 'deactivate_plugin_name' );

/**
 * Funkce s vykonym kodem pro cron ulohu
 */
function my_repeat_function() {
   file_put_contents( realpath(dirname(__FILE__)) . "/cron.txt", date( "d.m.Y H:i:s" ) . " cron\n", FILE_APPEND);
}

Doufám, že pomůže 🙂

PHP čtení dat z Google Analytics

Dnes si ukážeme postup jak se z PHP s Analytics API připojit na Google Analytics a získat data.

1) Aktivace Analytics API

Abychom mohli začít používat Google Analytics API, musíme vytvořit nový projekt v Google Developers Console a povolit API. Přímý odkaz na vytvoření nového projektu v Google Developer Console a aktivace Google Analytics API

Případně můžete aktivovat rozhraní API Google Analytics v Developer konzoli následujícím způsobem:

V menu vybereme: APIs & auth -> APIs. Vyhledáme Analytics API a ektivujeme tlačítkem Enable API.

2) Vytvoření client ID

Aby se bylo možné připojit na API, musíme vytvořit uživatele pod kterým se budeme přihlašovat. Uděláme to v sekci: APIs & auth -> Credentials kde vytvoříme nový Service accoun.

Klikneme na modré rozbalovací tlačítko Add credentials a vybereme Service account. Nově vytvořený uživatel se nebude přihlašovat heslem ale klíčem. KEY TYPE zvolíme volbu na P12.

ga-create-service-account-p12

Po vytvoření se nám stáhne klíč pro přihlášení (project-xxxxxxxxxx.p12) a vytvoří uživatel s podobným e-mailem: xxxxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com

Oboje údaje jsou velice důležité a dobře si je uložte. Budeme je potřebovat, protože se přes něj budeme v PHP hlásit k Analytics API 🙂

3) Přidání účtu do Google Analytics

Přes účet v bodu 2 se budeme hlásit k API a získávat data. Proto tedy nově vytvořený účet přidáme k požadovanému profilu v Google Analytics. Po přihlášení vybereme v horním pruhu položku Správce. Ve sloupci SLUŽBA (prostřední sloupec) vybereme požadovanou službu a klikneme na Správa uživatelů. Přidáme nového uživatele: Do pole Přidat oprávnění pro uživatele: přidáme vytvořený email (v mém případě: xxxxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com) a ponecháme oprávnění: Číst a analyzovat.

4) Napojení na Analytics API z PHP

Stáhneme knihovnu google-api-php-client: https://github.com/google/google-api-php-client

Knihovnu je také možné stáhnout přes composer:

composer require google/apiclient

Použijeme tento ukázkový kód, který zobrazuje počet návštěv za posledních 7 dní. Stačí pouze změnit tyto hodnoty: ZDE_ZADEJTE_EMAIL_VYTVOŘENÝ_V_KROKU_2 a ZDE_ZADEJTE_KLÍČ_VYTVOŘENÝ_V_KROKU_2

<?php

function getService()
{
  // Creates and returns the Analytics service object.

  // Load the Google API PHP Client Library.
  require_once 'google-api-php-client/src/Google/autoload.php';

  // Use the developers console and replace the values with your
  // service account email, and relative location of your key file.
  $service_account_email = 'ZDE_ZADEJTE_EMAIL_VYTVOŘENÝ_V_KROKU_2';
  $key_file_location = 'ZDE_ZADEJTE_KLÍČ_VYTVOŘENÝ_V_KROKU_2.p12>';

  // Create and configure a new client object.
  $client = new Google_Client();
  $client->setApplicationName("HelloAnalytics");
  $analytics = new Google_Service_Analytics($client);

  // Read the generated client_secrets.p12 key.
  $key = file_get_contents($key_file_location);
  $cred = new Google_Auth_AssertionCredentials(
      $service_account_email,
      array(Google_Service_Analytics::ANALYTICS_READONLY),
      $key
  );
  $client->setAssertionCredentials($cred);
  if($client->getAuth()->isAccessTokenExpired()) {
    $client->getAuth()->refreshTokenWithAssertion($cred);
  }

  return $analytics;
}

function getFirstprofileId(&$analytics) {
  // Get the user's first view (profile) ID.

  // Get the list of accounts for the authorized user.
  $accounts = $analytics->management_accounts->listManagementAccounts();

  if (count($accounts->getItems()) > 0) {
    $items = $accounts->getItems();
    $firstAccountId = $items[0]->getId();

    // Get the list of properties for the authorized user.
    $properties = $analytics->management_webproperties
        ->listManagementWebproperties($firstAccountId);

    if (count($properties->getItems()) > 0) {
      $items = $properties->getItems();
      $firstPropertyId = $items[0]->getId();

      // Get the list of views (profiles) for the authorized user.
      $profiles = $analytics->management_profiles
          ->listManagementProfiles($firstAccountId, $firstPropertyId);

      if (count($profiles->getItems()) > 0) {
        $items = $profiles->getItems();

        // Return the first view (profile) ID.
        return $items[0]->getId();

      } else {
        throw new Exception('No views (profiles) found for this user.');
      }
    } else {
      throw new Exception('No properties found for this user.');
    }
  } else {
    throw new Exception('No accounts found for this user.');
  }
}

function getResults(&$analytics, $profileId) {
  // Calls the Core Reporting API and queries for the number of sessions
  // for the last seven days.
   return $analytics->data_ga->get(
       'ga:' . $profileId,
       '7daysAgo',
       'today',
       'ga:sessions');
}

function printResults(&$results) {
  // Parses the response from the Core Reporting API and prints
  // the profile name and total sessions.
  if (count($results->getRows()) > 0) {

    // Get the profile name.
    $profileName = $results->getProfileInfo()->getProfileName();

    // Get the entry for the first entry in the first row.
    $rows = $results->getRows();
    $sessions = $rows[0][0];

    // Print the results.
    print "First view (profile) found: $profileName\n";
    print "Total sessions: $sessions\n";
  } else {
    print "No results found.\n";
  }
}

$analytics = getService();
$profile = getFirstProfileId($analytics);
$results = getResults($analytics, $profile);
printResults($results);

 

Google Analytics – kód pro elektronický obchod

Poprosil mne kolega, zda bych mu nepomohl nastavit měřící kód pro elektronický obchod v GA. Po pár slepých uličkách jsem se dostal k cíli. Abych vám ušetřil čas uvádím zde kód který připíše konverzi (dokončení objednávky) v elektronickém obchodě.

Bohužel se mi nepovedlo nalézt „živé“ sledování dokončených objednávek. Musíte vydržet a do 24hodin se objednávky objeví v sekci: Konverze -> Elektronický obchod -> Přehled

POZOR: tento kód je funkční pouze pro Universal Analytics

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>NAKOUPENO</title>
</head>

<body>

nakoupeno
<script>
    //---------------- START GA ------------------
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
                (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    ga('create', 'UA-XXXXXXX-YY', 'auto');
    ga('send', 'pageview');
    //---------------- END GA ------------------

    //SHOP start
    ga('require', 'ecommerce');

    ga('ecommerce:addTransaction', {
        'id': '1234',                    // Transaction ID. Required.
        'affiliation': 'Web Site',
        'revenue': '66.31',
        'shipping': '5.25',
        'tax': '5.05'
    });
    ga('ecommerce:addItem', {
        'id': '1234',                     // Transaction ID. Required.
        'name': 'Fluffy Pink Bunnies',    // Product name. Required.
        'sku': 'DD23444',                 // SKU/code.
        'category': 'Party Toys',         // Category or variation.
        'price': '11.99',                 // Unit price.
        'quantity': '1'                   // Quantity.
    });

    ga('ecommerce:send');
    //SHOP end

</script>

</body>
</html>

Popis jednotlivých položek najdete v dokumentaci: https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce

WooCommerce: získání všech tagů a kategorií

Poslední dobou dělám věci okolo WordPressu a Woocommerce. Dnes si ukážeme jak v doplňku získávám všechny kategorie a tagy.

Jak získat všechny tagy?

Function Reference/get terms

$taxonomies = 'product_tag';
$args = array(
   'taxonomy'     => 'product_cat',
   'hide_empty'   => 0
);
$terms = get_terms($taxonomies, $args);
foreach ($terms as $term) {
   //var_dump($term);
   //$termLink = get_term_link( $term );
   echo $term->name;
}

 

Jak získat všechny kategorie?

Function Reference/get categories

$args = array(
   'taxonomy'     => 'product_cat',
   'hide_empty'   => 0
);
$categories = get_categories( $args );
foreach( $categories as $category ) {
   //var_dump($category);
   //$categoryLink = get_category_link( $category );
   echo $category->name;
}

 

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.