Kedves látogató!
A fejlesztői blogomban olyan témákkal fogok foglalkozni, amelyek nem a JAVA programozási nyelv alapjainak ismertetését célozzák meg, hanem a speciálisabb témákról fogok írni, amelyek már feltétélezik a JAVA nyelv alapszintű ismeretét.
A stratégiám az, hogy egyszerű feladatok révén mutassam be a mondandómat. Hiszen a programozás mindig ugy kezdődik, hogy először egy feladat van és ahhoz keressük meg a megfelelő programozási nyelvet, ami jelen esetben a JAVA lesz. Néhany esetben ettől eltérő környezetek - pl. PHP - is alkalmazva lesznak, hogy könnyen tudjam szemléltetni a mondanivalómat.
A natív JAVA mellett az Android SDK és a Google Web Toolkit (GWT) használatának témakörében is fogok cikkeket megjelentetni, hiszen ezek a környezetek tulajdonképpen csak az API-ban térnek el a JAVA-tól. A fejlesztői környezet kiválasztásánál a JAVA-hoz legjobban illeszkedőt választottam, ami a Netbeans. A szerver oldali funkciókat PHP-ben programoztam le, mivel szemléletesebb és egyszerűbb a használata mint a JAVA alapú szervereké nem beszélve a kiszolgálás sebességéről.
A programozási tanácsokon túlmenően a fejlesztésekkel összefüggő egyéb témákban is plublikálok cikkeket. A cikkekben közölt kódok és eljárások szabadon felhasználhatók, de a működésükért garanciát nem vállalok.
2018.04.16.
SOAP alapú kliens
A kliens-szerver alapú kommunikáció egyik legelterjedtebb formája a webes világban a web service. Ezt többféleképpen meg lehet valósítani, kezdve a legegyszerűbb
get metódusú kapcsolattól az XML RPC-ig sokféle típusa létezik. A feladattól fuggően lehet szabványos, vagy szabványtól eltérő megoldásokat használni. Most egy konkrét, szabványos formáját nézzük meg, a Simple Object Access Protocol - vagy röviden a SOAP - működését.
További információkat a SOAP-ról itt találsz: https://hu.wikipedia.org/wiki/SOAP
A feladat: Az egyszerűség kedvéért két egész szám összeadását fogjuk webservice-en keresztül elvégezni, ennek mintájára bármely más művelet kidolgozására is jól használható az alábbi folyamat.
A SZERVER A szerver oldalról egy PHP alapra épülő szkript fogja kiszolgálni a kliens oldalt. A SOAP web service megvalósításához a nusoap osztálykönyvárt használom, mivel professzinálisabb megoldásokat kínál a fejleszők számára mint a PHP natív soap osztálya. Ilyenek pl. a dinamikus WSDL állomány generálása ami bizonyos esetekben nélkülözhetetlen a szerver oldal paraméterezéséhez, vagy a szépen kialakított sugója, ami szemléletesen mutatja meg, hogy a webservice milyen funkciókat tartalmaz és azokat hogyan kell paraméterezni.
Az output JSON tömb lesz, mivel ezt könnyen elő lehet állítani PHP-ből és a JAVA-ban is megoldható a visszafejtése. A PHP kódot helyezzük el a szerveren, jelen esetben most ezen a címen lesz elérhető: http://192.168.1.2/soap/index.php
Ezek tükrében a szerver oldal így alakul:
<?php
ini_set ('display_errors' , 1 );
// NUSOAP osztalykonyvtar betoltese
require_once("soap/nusoap.php");
// Uj SOAP szerver letrehozasa
$server = new soap_server();
// A web szerviz beallitas
$server->configureWSDL("tesztservice");
// Itt definialjuk a fuggveny nevet es a input/output-ot
$server->register('osszead',
array("a" => "xsd:string", "b" => "xsd:string"),
array("return" => "xsd:string"));
// A szamitast vegzo fuggveny
// $a - elso szam
// $b - masodik szam
// return - tomb amely az 1. indexen hozza a ket szam osszeget
function osszead($a, $b)
{
$aa[1]=($a+$b);
return json_encode($aa);
}
$POST_DATA = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
// Adatok kuldese a webszervizen keresztul
$server->service($POST_DATA);
exit();
?>
A KLIENS A kliens oldal fejlesztésénél olyan osztálykönyvtárat is fogunk használni, amely a Maven Repository-ból szerezhető be ezért a JAVA projektet már célirányosan Maven project-ként kell létrehozni a Netbeans-ben. Konkrétan a JSON kezeléséhez szükséges osztálykönyvtár integrációjáról van szó, amit online fog beszerezni a beállítás révén a projekt. A függőséget a Project Files / pom.xml állományban állíthatjuk be a "dependencies" blokkban, valahogy így:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ifsoft</groupId>
<artifactId>MavenSoap</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20090211</version>
<type>jar</type>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<name>MavenSoap</name>
</project>
A folyamat következő lépése a SOAP kommunikációt lehetővé tévő alosztály létrehozása. A kapcsolat felépítésén túl ebben fog szerepelni a számítási művelet eredményének lekérdezése és feldolgozása is. Az alosztály egy önálló package-ben helyeztem el.
package soap;
import static java.lang.Integer.parseInt;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import org.json.JSONObject;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Soap {
String soapEndpointUrl; // A hasznalni kivant webservice cime
String soapAction; // A hasznalni kivant webservice cime
String myNamespace; // A hasznalni kivant webservice nevtere
String myNamespaceURI; // A nevter eleresi utvonala
// Az inputok elhelyezese
private int a = 0;
private int b = 0;
// Az eredmeny tarolasi helye
private int eredmeny = 0;
// Az osztaly felparameterezese a konstruktor altal
public Soap (String soapEndpointUrl, String soapAction, String myNamespace, String myNamespaceURI) {
this.soapEndpointUrl = soapEndpointUrl;
this.soapAction = soapAction;
this.myNamespace = myNamespace;
this.myNamespaceURI = myNamespaceURI;
}
// A SOAP kuldemeny osszeallitasa
private void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException {
SOAPPart soapPart = soapMessage.getSOAPPart();
// A SOAP kuldemeny keretmunkaja
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration(this.myNamespace, this.myNamespaceURI);
// A SOAP kuldemeny teste
SOAPBody soapBody = envelope.getBody();
// A webservice meghivando metodusanak a neve
SOAPElement soapBodyElem = soapBody.addChildElement("osszead", this.myNamespace);
// A metodushoz adjuk a ket parametert
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("a", this.myNamespace);
SOAPElement soapBodyElem2 = soapBodyElem.addChildElement("b", this.myNamespace);
// Es feltoltjuk a ket bemeneti ertekkel
soapBodyElem1.addTextNode(String.valueOf(this.a));
soapBodyElem2.addTextNode(String.valueOf(this.b));
}
// A kliens oldali feldolgozo metodus, amely lenyegeben inicializalja a muvelet parametereit, meghivja a webservice-t es elhozza az adatokat
// input: a, b - a ket bemeneti parameter
// output: a muvelet eredménye
public int osszead (int a, int b) {
// bemeneti parameter inicializalasa
this.a=a;
this.b=b;
try {
// SOAP kapcsolat felepitese
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// webservice meghivasa
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(this.soapAction), this.soapEndpointUrl);
// az eredmeny lekerzese
SOAPBody soapBody = soapResponse.getSOAPBody();
// az eredmeny feldolgozasa
NodeList nodes = soapBody.getElementsByTagName("return");
Node node = nodes.item(0);
// az eredmeny json tombben erkezett
JSONObject obj = new JSONObject(node.getTextContent());
// az eredment attoltjuk egy lokalis valtozoba
this.eredmeny = parseInt(obj.get(String.valueOf(1)).toString());
// A SOAP kapcsolat lezarasa
soapConnection.close();
} catch (Exception e) {
e.printStackTrace();
this.eredmeny = 0;
}
// az eredmenyt vissza adjuk
return this.eredmeny;
}
// a SOAP keres osszeallitasa
private SOAPMessage createSOAPRequest(String soapAction) throws Exception {
// a keres inicializalasa
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
// a kuldemeny integralasa
createSoapEnvelope(soapMessage);
// az uzenet header osszeallitasa
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", soapAction);
// a keres elmentese
soapMessage.saveChanges();
return soapMessage;
}
}
A műveletsor következő lépése egy paraméterező alosztlay létrehozása, amely lehetővé teszi a SOAP folyamat elindítását valamint az eredmeny lekerdezeset is.
package com.ifsoft.soapmaven.soap;
import soap.Soap;
public class Workflow {
// A SOAP kapcsolat parameteresi
String soapEndpointUrl = "http://192.168.1.2/soap/index.php";
String soapAction = "http://192.168.1.2/soap/index.php/";
String myNamespace = "tesztservice";
String myNamespaceURI = "http://192.168.1.2/soap/tesztservice/";
// Egy metodussal beinditjuk a folyamatot, majd kiirjuk az eredmenyt
public void teszt () {
// Csatalakozas a sajat SOAP osztalyunkhoz
Soap soap = new Soap (this.soapEndpointUrl, this.soapAction+"osszead", this.myNamespace, this.myNamespaceURI);
// Az osszedas muvelet eredmenyenek kiirasa
System.out.println("EREDMENY: "+soap.osszead(1152, 143));
}
}
Ahhoz, hogy a JAVA környezet teljes legyen meg szükség van egy inditó alaposztályra.
package com.ifsoft.soapmaven.soap;
public class Main {
public static void main(String[] args) {
// munkafolyamat inicializacioja
Workflow wf = new Workflow();
// teszt inditasa
wf.teszt();
}
}
Amennyiben a feladat többféle webservice műveletet használ (pl. lenne még egy szorzási funkció is), akkor a legegyszerűbb a "package soap;" alatt létrehozni további osztályokat, és kidolgozni metódusonként. De akár egyetlen osztályba is behúzható az összes további művelet. De ez már a kedves olvasó fantáziájára van bízva. I.F.
2018.04.18.
Android debuggolás WIFI-vel
Az Android debuggolás alapesetben az USB porthoz kötötten jelenik meg. Az eszközt a számítógéppel egy USB kábellel kötjük össze úgy, hogy az eszközön bekapcsoljuk a fejlesztői lehetőségek között az USB debuggolást, valamint a számítógépen elindítjuk az ADB-t (Android Debug Bridge), és innestől akár videót is rögzíthetünk a készüléken történt eseményekről.Ez mindaddig elég amíg nem akarunk az Androidos eszközhöz valamilyen USB-n keresztül csatlakozó hardvert használni, olyat mint az egér, a billentyűzet vagy a játékvezérlő. A készülékeknek általában csak egyetlen USB portja van, az OTG HUB-okat -, amelyekkel ki lehet elvben terjeszteni az USB portok számát - pedig csak a készülékek kis része támogatja. Így nem marad más lehetőség csak valamilyen más összekapcsolási mód. Például a vezeték nélküli hálózat.
Az alább ismertetett megoldás a modernebb (API level 15<) androidos készülékekkel általában működik. A kapcsolat felépítéséhez szükséges az USB kábel is egy pontig, majd azon túl már nem. Ezen felül fontos dolog, hogy mind a számítógépnek, mind az androidos eszköznek ugyanarra a WIFI-s hotspotra kell csatlakoznia. Az eljárás úgy nem mőködik, hogy egy routerre kapcsolódnak de a számítógép kábellel az eszköz pedig WIFIvel. A legstabilabb megoldás az, ha maga a számitógép a WIFI hotspot, és erre csatlakoztatjuk. Az eljárást Windows környezetben fogjuk kipróbálni. Előfeltétele az, hogy az Android SDK platform tools telepítve legyen a számítógépre.
A kapcsolat kialakításánek lépései:
1) Üzemeljük be a számítógépet és az androidos eszközt úgy, hogy ugyanazon a WIFI hálózaton legyenek.
2) Csatlakoztassuk az eszközt USB kábellel a számítógéphez. Az eszközön állítsuk be az USB debuggolast a fejlesztői menüben.
3) Szükség lesz az eszköz hálózati IP számára. Ezt kétféleképpen deríthetjük ki.
- Inditsuk el az Androidos eszközön a 'Settings' applikációt, válasszuk ki az 'About Tablet' menüt, majd kattintsunk a 'Status' almenüre. Itt találni fogunk egy olyan részt, hogy IP Address ezt jegyezzük fel.
- Amennyiben telepítettünk valamilyen terminál emulátort az eszközre indítsuk azt el, és vagy az IFCONFIG vagy a NETCFG paranccsal is lekérdezhetjük az IP számot.
4) Most az ADB kapcsolat felépítését fogjuk átalakítani egy batch script segítségével a számítógép oldaláról nézve, úgy hogy TCP/IP környezetben is működhessen. Az alábbi scriptet mindenkinek annak megfelelően kell átalakítani amilyen paraméterekkel rendelkezik:
- a "c:\Users\IFSOFT\AppData\Local\Android\sdk\platform-tools\adb.exe" az ADB utvonalát adja meg, ezt le kell cserélned arra, ami az adott környezetben az útvonala.
- a 3. pontban rögzített IP szám kerüljon ennek a helyére "192.168.1.3".
"c:\Users\IFSOFT\AppData\Local\Android\sdk\platform-tools\adb.exe" kill-server
timeout /t 3
"c:\Users\IFSOFT\AppData\Local\Android\sdk\platform-tools\adb.exe" usb
timeout /t 3
"c:\Users\IFSOFT\AppData\Local\Android\sdk\platform-tools\adb.exe" tcpip 5555
timeout /t 3
"c:\Users\IFSOFT\AppData\Local\Android\sdk\platform-tools\adb.exe" connect 192.168.1.3:5555
timeout /t 3
"c:\Users\IFSOFT\AppData\Local\Android\sdk\platform-tools\adb.exe" devices
timeout /t 15
5) Ha a módosításokat elvégezted, mentsd el a scriptet pl. "adbwifi.bat" néven.
6) Indítsd el a scriptet. Ha mindent jól csináltál a 'devices' parancs már 2 eszközt listáz. Ekkor le lehet csatlakoztatni az USB kábelt az Androidos eszközről, mivel felépült a WIFI-s kapcsolat. Innestől az eszközt tudod egérrel, billentyűzettel vagy játékvezérlővel hasznáni, úgy hogy közben a debuggolás is működik. A kialakított kapcsolatot a leglátványosabban egy video rözítésével lehet ellenőrízni. Erre is mutatok egy batch scriptet. Az útvonalakat át kell alakítanod a környezetnek megfelelően ahonnan használod.
"c:\Users\IFSOFT\AppData\Local\Android\sdk\platform-tools\adb.exe" shell screenrecord /sdcard/tesztvideo.mp4 --time-limit 60 --size 1760x1024
"c:\Users\IFSOFT\AppData\Local\Android\sdk\platform-tools\adb.exe" pull /sdcard/tesztvideo.mp4
timeout /t 5
Ez 60 másodperces videót rögzít az eszközről.
Előfordulhat hogy a WIFI-s kapcsolat nem épül fel azonnal. Ilyenkor érdemes többször futtatni egymás után a 'adbwifi.bat' scriptet, ha így is sikertelen
akkor próbáld meg újraindítani az Androidos eszközt, ha ezek után sem megy próbáld meg a 'timeout /t 3' -okat magasabbra venni, és ha még ezután sem műkodik akkor valószínűleg a készülék nem támogatja.I.F.
2018.04.24.
Adatvédelem
Frissítve: 2018.04.24.
Definíciók: Cookie: A web szervár által létrehozott információs csomag, amelyet a szerver átad a kliens web böngészőjének és az letárolja a felhasználó gépére. Amikor a kliens ujból meglátogatja az oldalt az információs csomagot átadja a szervernek, ezáltal azonosítva a felhasználót.
Google Analytics: A Google Inc. szolgátatása, amely a weboldal látogatóinak a weboldalon folytatott tevékenységéről készít statisztikát.
Google Adsense: A Google Inc. által létrehozott hírdetésközvetítő szolgáltatás.
Alapelvek: Az ifsoft.hu weboldal használata nincs regisztrációhoz kötve, és a felhasználóktól nem kér semmilyen személyes adatot.
A felhasználók nem szerkeszthetik az oldal tartalmát, csak a weboldal tulajdonosa.
A weboldal tulajdonosa rendszeresen karbantartja és frissíti az adatvédelmi irányelveit.
A felhasználói élmény javítása és az oldal továbbfejlesztése érdekében fontosak a felhasználói statisztikák. Az adatgyűjtés eszköze a Google Analytics. A Google Analytics a weboldal teljesítményének méréséhez cookie-kat használ.
A Google az összegyűjtött adatokat esetleg megoszthatja más szolgáltatásaival is, ugy mint az Google Adsense.
A Google adatkezelési jogosultságát bármikor visszavonhatja.
A Google Analytics adatkezelési szabályztát itt találja: https://support.google.com/analytics/answer/6004245?hl=hu
A weboldal fizetett hírdetéseket tartalmaz. Ennek az a célja, hogy anyagi alapot teremtsen a weboldal fenntartásához. A hírdetések megjelenítésének eszköze a Google Adsense.
A Google Adsense adatkezelési szabályzatát itt találja: https://policies.google.com/privacy?hl=hu Kapcsolat: leekeechild@gmail.com