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 5Ez 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