diff --git a/phoneClients/j2me/.gitignore b/phoneClients/j2me/.gitignore deleted file mode 100644 index 1f773d9..0000000 --- a/phoneClients/j2me/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.class - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.ear - diff --git a/phoneClients/j2me/README.md b/phoneClients/j2me/README.md deleted file mode 100644 index b740908..0000000 --- a/phoneClients/j2me/README.md +++ /dev/null @@ -1 +0,0 @@ -this is the j2me/javaMe client for gpstracker. diff --git a/phoneClients/javaMe/.gitignore b/phoneClients/javaMe/.gitignore new file mode 100644 index 0000000..1f773d9 --- /dev/null +++ b/phoneClients/javaMe/.gitignore @@ -0,0 +1,10 @@ +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + diff --git a/phoneClients/javaMe/README.md b/phoneClients/javaMe/README.md new file mode 100644 index 0000000..9a279e0 --- /dev/null +++ b/phoneClients/javaMe/README.md @@ -0,0 +1 @@ +this is the javaMe / j2me client for gpstracker. diff --git a/phoneClients/javaMe/build.xml b/phoneClients/javaMe/build.xml new file mode 100644 index 0000000..46a50e0 --- /dev/null +++ b/phoneClients/javaMe/build.xml @@ -0,0 +1,83 @@ + + + + + + Builds, tests, and runs the project . + + + diff --git a/phoneClients/javaMe/build/.timestamp b/phoneClients/javaMe/build/.timestamp new file mode 100644 index 0000000..999b584 --- /dev/null +++ b/phoneClients/javaMe/build/.timestamp @@ -0,0 +1 @@ +ignore me \ No newline at end of file diff --git a/phoneClients/javaMe/build/manifest.mf b/phoneClients/javaMe/build/manifest.mf new file mode 100644 index 0000000..bd06b7b --- /dev/null +++ b/phoneClients/javaMe/build/manifest.mf @@ -0,0 +1,6 @@ +MIDlet-1: GpsTracker, , com.websmithing.gpstracker.GpsTracker +MIDlet-Vendor: Vendor +MIDlet-Name: GpsTracker +MIDlet-Version: 1.0 +MicroEdition-Configuration: CLDC-1.1 +MicroEdition-Profile: MIDP-2.1 diff --git a/phoneClients/javaMe/build/preprocessed/com/websmithing/gpstracker/GpsHelper.java b/phoneClients/javaMe/build/preprocessed/com/websmithing/gpstracker/GpsHelper.java new file mode 100644 index 0000000..2b1fc68 --- /dev/null +++ b/phoneClients/javaMe/build/preprocessed/com/websmithing/gpstracker/GpsHelper.java @@ -0,0 +1,164 @@ +// +// GpsHelper.java +// GpsTracker +// +// Created by Nick Fox on 12/1/13. +// Copyright (c) 2013 Nick Fox. All rights reserved. +// + +package com.websmithing.gpstracker; + + +import javax.microedition.location.*; +import java.util.Calendar; +import java.util.Date; + +public class GpsHelper implements LocationListener { + + private LocationProvider locationProvider = null; + private Coordinates oldCoordinates = null, currentCoordinates = null; + private float distance = 0; + private int azimuth = 0; + private String uploadWebsite; + private String queryString; + private GpsTracker midlet; + private int interval; + protected Calendar currentTime; + protected long sessionID; + + + public GpsHelper(GpsTracker Midlet, int Interval, String UploadWebsite){ + currentTime = Calendar.getInstance(); + sessionID = System.currentTimeMillis(); + this.midlet = Midlet; + this.interval = Interval; + this.uploadWebsite = UploadWebsite; + } + + // getting the gps location is based on an interval in seconds. for instance, + // the location is gotten once a minute, sent to the website to be stored in + // the DB (and then viewed on Google map) and used to retrieve a map tile (image) + // to be diplayed on the phone + + public void startGPS() { + if (locationProvider == null) { + createLocationProvider(); + + Thread locationThread = new Thread() { + public void run(){ + createLocationListener(); + } + }; + locationThread.start(); + } + } + + // this allows us to change how often the gps location is gotten + public void changeInterval(int Interval) { + if (locationProvider != null) { + locationProvider.setLocationListener(this, Interval, -1, -1); + } + } + + private void createLocationProvider() { + Criteria cr = new Criteria(); + + try { + locationProvider = LocationProvider.getInstance(cr); + } catch (Exception e) { + midlet.log("GPS.createLocationProvider: " + e); + } + } + + private void createLocationListener(){ + // 2cd value is interval in seconds + try { + locationProvider.setLocationListener(this, interval, -1, -1); + } catch (Exception e) { + midlet.log("GPS.createLocationListener: " + e); + } + } + + public void locationUpdated(LocationProvider provider, final Location location) { + // get new location from locationProvider + + try { + Thread getLocationThread = new Thread(){ + public void run(){ + getLocation(location); + } + }; + + getLocationThread.start(); + } catch (Exception e) { + midlet.log("GPS.locationUpdated: " + e); + } + } + + public void providerStateChanged(LocationProvider provider, int newState) {} + + private void getLocation(Location location){ + float speed = 0; + + try { + QualifiedCoordinates qualifiedCoordinates = location.getQualifiedCoordinates(); + + qualifiedCoordinates.getLatitude(); + + if (oldCoordinates == null){ + oldCoordinates = new Coordinates(qualifiedCoordinates.getLatitude(), + qualifiedCoordinates.getLongitude(), + qualifiedCoordinates.getAltitude()); + } else { + if (!Float.isNaN( qualifiedCoordinates.distance(oldCoordinates))) { + distance += qualifiedCoordinates.distance(oldCoordinates); + } + + currentCoordinates = new Coordinates(qualifiedCoordinates.getLatitude(), + qualifiedCoordinates.getLongitude(), + qualifiedCoordinates.getAltitude()); + azimuth = (int)oldCoordinates.azimuthTo(currentCoordinates); + oldCoordinates.setAltitude(qualifiedCoordinates.getAltitude()); + oldCoordinates.setLatitude(qualifiedCoordinates.getLatitude()); + oldCoordinates.setLongitude(qualifiedCoordinates.getLongitude()); + + } + + if (qualifiedCoordinates != null){ + Date d = new Date(); + + if (!Float.isNaN(location.getSpeed())) { + speed = location.getSpeed(); + } + + queryString = "?lat=" + String.valueOf(qualifiedCoordinates.getLatitude()) + + "&lng=" + String.valueOf(qualifiedCoordinates.getLongitude()) + + "&mph=" + String.valueOf((int)(speed/1609*3600)) + + "&dir=" + String.valueOf(azimuth) + + "&dis=" + String.valueOf((int)(distance/1609)) + + "&dt=" + d.toString() + + "&lm=" + location.getLocationMethod() + + "&pn=" + midlet.phoneNumber + + "&sid=" + String.valueOf(sessionID) + + "&acc=" + String.valueOf((int)(qualifiedCoordinates.getHorizontalAccuracy()*3.28)) + + "&iv=" + String.valueOf(location.isValid()) + + "&info=" + location.getExtraInfo("text/plain") + + "&zm=" + midlet.zoomLevel + + "&h=" + midlet.height + + "&w=" + midlet.width; + + // with our query string built, we create a networker object to send the + // query to our website and get the map image and update the DB + NetWorker worker = new NetWorker(midlet, uploadWebsite); + worker.getUrl(queryString); + + } + + } catch (Exception e) { + midlet.log("GPS.getLocation: " + e); + } + } +} + + + diff --git a/phoneClients/javaMe/build/preprocessed/com/websmithing/gpstracker/GpsTracker.java b/phoneClients/javaMe/build/preprocessed/com/websmithing/gpstracker/GpsTracker.java new file mode 100644 index 0000000..f30f850 --- /dev/null +++ b/phoneClients/javaMe/build/preprocessed/com/websmithing/gpstracker/GpsTracker.java @@ -0,0 +1,285 @@ +// +// GpsTracker.java +// GpsTracker +// +// Created by Nick Fox on 12/1/13. +// Copyright (c) 2013 Nick Fox. All rights reserved. +// + +package com.websmithing.gpstracker; + +import javax.microedition.midlet.*; +import javax.microedition.lcdui.*; +import java.util.Calendar; + +public class GpsTracker extends MIDlet implements CommandListener, ItemStateListener { + private Display display; + private Form form; + private Form zoomScreen; + private Form settingsScreen; + private Command exitCmd; + private Command saveCmd; + private Command zoomCmd; + private Command settingsCmd; + private Command backCmd; + private TextField phoneNumberTextField; + private TextField uploadWebsiteTextField; + private Gauge zoomGauge; + private StringItem zoomStringItem; + private ChoiceGroup updateIntervalCG; + private String updateInterval; + private int[] iTimes = {60, 300, 900}; + + private RmsHelper rms; + private GpsHelper gps; + + private String uploadWebsite; + private String defaultUploadWebsite = "http://www.websmithing.com/gpstracker/GetGoogleMap2.php"; + + protected String phoneNumber; + protected String zoomLevel; + protected int height, width; + protected Calendar currentTime; + protected long sessionID; + protected Image im = null; + + public GpsTracker(){ + form = new Form("GpsTracker"); + display = Display.getDisplay(this); + exitCmd = new Command("Exit", Command.EXIT, 1); + zoomCmd = new Command("Zoom", Command.SCREEN, 2); + settingsCmd = new Command("Settings", Command.SCREEN, 3); + + form.addCommand(exitCmd); + form.addCommand(zoomCmd); + form.addCommand(settingsCmd); + form.setCommandListener(this); + + display.setCurrent(form); + currentTime = Calendar.getInstance(); + sessionID = System.currentTimeMillis(); + height = form.getHeight(); + width = form.getWidth(); + + // RMS is the phone's built in storage, kind of like a database, but + // it only stores name-value pairs (like an associative array or hashtable). + // eveything is stored as a string. + getSettingsFromRMS(); + + // the phone number field is the only empty field when the application is + // first loaded. it does not have to be a phone number, it can be any string, + // but for uniqueness, it's best to use a phone number. this only has to be + // done once. + if (hasPhoneNumber()) { + startGPS(); + displayInterval(); + } + } + + public void startApp() { + if ( form != null ) { + display.setCurrent(form); + } + } + + // let the user know how often map will be updated + private void displayInterval() { + int tempTime = iTimes[Integer.parseInt(updateInterval)]/60; + + display.setCurrent(form); + form.deleteAll(); + + if (tempTime == 1) { + log("Getting map once a minute..."); + } + else { + log("Getting map every " + String.valueOf(tempTime) + " minutes..."); + } + } + + private void loadZoomScreen() { + zoomScreen = new Form("Zoom"); + zoomGauge = new Gauge("Google Map Zoom", true, 17, Integer.parseInt(zoomLevel)); + zoomStringItem = new StringItem(null, ""); + zoomStringItem.setText("Zoom level: " + zoomGauge.getValue()); + backCmd = new Command("Back", Command.SCREEN, 1); + + zoomScreen.append(zoomGauge); + zoomScreen.append(zoomStringItem); + zoomScreen.addCommand(backCmd); + zoomScreen.setItemStateListener(this); + zoomScreen.setCommandListener(this); + + display.setCurrent(zoomScreen); + } + + // this method is called every time the zoom guage changes value. the zoom level is + // reset and saved + public void itemStateChanged(Item item) { + if (item == zoomGauge) { + zoomStringItem.setText("Zoom level: " + zoomGauge.getValue()); + zoomLevel = String.valueOf(zoomGauge.getValue()); + + try { + rms.put("zoomLevel", zoomLevel); + rms.save(); + } + catch (Exception e) { + log("GPSTracker.itemStateChanged: " + e); + } + } + } + + private void loadSettingsScreen() { + settingsScreen = new Form("Settings"); + + phoneNumberTextField = new TextField("Phone number or user name", phoneNumber, 20, TextField.ANY); + uploadWebsiteTextField = new TextField("Upload website", uploadWebsite, 100, TextField.ANY); + settingsScreen.append(phoneNumberTextField); + settingsScreen.append(uploadWebsiteTextField); + + String[] times = { "1 minute", "5 minutes", "15 minutes"}; + updateIntervalCG = new ChoiceGroup("Update map how often?", ChoiceGroup.EXCLUSIVE, times, null); + updateIntervalCG.setSelectedIndex(Integer.parseInt(updateInterval), true); + settingsScreen.append(updateIntervalCG); + + saveCmd = new Command("Save", Command.SCREEN, 1); + settingsScreen.addCommand(saveCmd); + + settingsScreen.setCommandListener(this); + display.setCurrent(settingsScreen); + } + + // get the settings from the phone's storage and load 4 global variables + public void getSettingsFromRMS() { + try { + rms = new RmsHelper(this, "GPSTracker"); + + phoneNumber = rms.get("phoneNumber"); + uploadWebsite = rms.get("uploadWebsite"); + zoomLevel = rms.get("zoomLevel"); + updateInterval = rms.get("updateInterval"); + } + catch (Exception e) { + log("GPSTracker.getSettingsFromRMS: " + e); + } + + if ((uploadWebsite == null) || (uploadWebsite.trim().length() == 0)) { + uploadWebsite = defaultUploadWebsite; + } + + if ((zoomLevel == null) || (zoomLevel.trim().length() == 0)) { + zoomLevel = "12"; + } + if ((updateInterval == null) || (updateInterval.trim().length() == 0)) { + updateInterval = "1"; + } + } + + private boolean hasPhoneNumber() { + if ((phoneNumber == null) || (phoneNumber.trim().length() == 0)) { + log("Phone number required. Please go to settings."); + return false; + } + else { + return true; + } + } + + // gps is started with the update interval. the interval is the time in between + // map updates + private void startGPS() { + if (gps == null) { + gps = new GpsHelper(this, iTimes[Integer.parseInt(updateInterval)], uploadWebsite); + gps.startGPS(); + } + } + + // this is called when the user changes the interval in the settings screen + private void changeInterval() { + if (gps == null) { + startGPS(); + } + else { + gps.changeInterval(iTimes[Integer.parseInt(updateInterval)]); + } + } + + // save settings back to phone memory + private void saveSettingsToRMS() { + try { + phoneNumber = phoneNumberTextField.getString(); + uploadWebsite = uploadWebsiteTextField.getString(); + updateInterval = String.valueOf(updateIntervalCG.getSelectedIndex()); + + rms.put("phoneNumber", phoneNumber); + rms.put("uploadWebsite", uploadWebsite); + rms.put("updateInterval", updateInterval); + + rms.save(); + } + catch (Exception e) { + log("GPSTracker.saveSettings: " + e); + } + display.setCurrent(form); + } + + // this method displays the map image, it is called from the networker object + public void showMap(boolean flag) + { + if (flag == false) { + log("Map could not be downloaded."); + } + else { + ImageItem imageitem = new ImageItem(null, im, ImageItem.LAYOUT_DEFAULT, null); + + if(form.size()!= 0) { + form.set(0, imageitem); + } + else { + form.append(imageitem); + } + } + } + + public void log(String text) { + StringItem si = new StringItem(null, text); + si.setLayout(Item.LAYOUT_NEWLINE_AFTER); + form.append(si); + } + + public void commandAction(Command cmd, Displayable screen) { + if (cmd == exitCmd) { + shutDownApp(); + } + else if (cmd == saveCmd) { + saveSettingsToRMS(); + + if (hasPhoneNumber()) { + changeInterval(); + displayInterval(); + } + } + else if (cmd == settingsCmd) { + loadSettingsScreen(); + } + else if (cmd == zoomCmd) { + loadZoomScreen(); + } + else if (cmd == backCmd) { + displayInterval(); + } + } + + public void pauseApp() {} + + public void destroyApp(boolean unconditional) {} + + protected void shutDownApp() { + destroyApp(true); + notifyDestroyed(); + } +} + + + diff --git a/phoneClients/javaMe/build/preprocessed/com/websmithing/gpstracker/NetWorker.java b/phoneClients/javaMe/build/preprocessed/com/websmithing/gpstracker/NetWorker.java new file mode 100644 index 0000000..8fe5191 --- /dev/null +++ b/phoneClients/javaMe/build/preprocessed/com/websmithing/gpstracker/NetWorker.java @@ -0,0 +1,119 @@ +// +// NetWorker.java +// GpsTracker +// +// Created by Nick Fox on 12/1/13. +// Copyright (c) 2013 Nick Fox. All rights reserved. +// + +package com.websmithing.gpstracker; + +import javax.microedition.io.*; +import java.io.*; +import javax.microedition.lcdui.Image; + +public class NetWorker { + private GpsTracker midlet; + private String uploadWebsite; + int i = 1; + + public NetWorker(GpsTracker lbsMidlet, String UploadWebsite){ + this.midlet = lbsMidlet; + this.uploadWebsite = UploadWebsite; + } + + public void getUrl(String queryString) { + queryString = URLencodeSpaces(queryString); + String url = uploadWebsite + queryString; + HttpConnection httpConn = null; + InputStream inputStream = null; + DataInputStream iStrm = null; + ByteArrayOutputStream bStrm = null; + Image im = null; + + try{ + httpConn = (HttpConnection)Connector.open(url); + + if(httpConn.getResponseCode() == HttpConnection.HTTP_OK){ + inputStream = httpConn.openInputStream(); + iStrm = new DataInputStream(inputStream); + + byte imageData[]; + int length = (int)httpConn.getLength(); + + if(length != -1) { + imageData = new byte[length]; + iStrm.readFully(imageData); + } + else { //Length not available + bStrm = new ByteArrayOutputStream(); + int ch; + + while((ch = iStrm.read())!= -1) { + bStrm.write(ch); + } + imageData = bStrm.toByteArray(); + + } + im = Image.createImage(imageData, 0, imageData.length); + } + else { + midlet.log("NetWorker.getUrl responseCode: " + httpConn.getResponseCode()); + } + + } catch (Exception e) { + midlet.log("NetWorker.getUrl: " + e); + } + finally{ // Clean up + try{ + if(bStrm != null) + bStrm.close(); + if(iStrm != null) + iStrm.close(); + if(inputStream != null) + inputStream.close(); + if(httpConn != null) + httpConn.close(); + } + catch(Exception e){} + } + + // if we have successfully gotten a map image, then we want to display it + if( im == null) { + midlet.showMap(false); + } + else { + midlet.im = im; + midlet.showMap(true); + } + + } + + // http://forum.java.sun.com/thread.jspa?threadID=341790&messageID=1408555 + private String URLencodeSpaces(String s) + { + if (s != null) { + StringBuffer tmp = new StringBuffer(); + int i = 0; + try { + while (true) { + int b = (int)s.charAt(i++); + + if (b != 0x20) { + tmp.append((char)b); + } + else { + tmp.append("%"); + if (b <= 0xf) { + tmp.append("0"); + } + tmp.append(Integer.toHexString(b)); + } + } + } + catch (Exception e) {} + return tmp.toString(); + } + return null; + } +} diff --git a/phoneClients/javaMe/build/preprocessed/com/websmithing/gpstracker/RmsHelper.java b/phoneClients/javaMe/build/preprocessed/com/websmithing/gpstracker/RmsHelper.java new file mode 100644 index 0000000..08e624a --- /dev/null +++ b/phoneClients/javaMe/build/preprocessed/com/websmithing/gpstracker/RmsHelper.java @@ -0,0 +1,88 @@ +// +// RmsHelper.java +// GpsTracker +// +// Created by Nick Fox on 12/1/13. +// Copyright (c) 2013 Nick Fox. All rights reserved. +// + +package com.websmithing.gpstracker; + +import java.util.*; +import javax.microedition.rms.*; + +public class RmsHelper { + private GpsTracker midlet; + private String mRecordStoreName; + private Hashtable mHashtable; + + public RmsHelper(GpsTracker Midlet, String recordStoreName) throws RecordStoreException { + this.midlet = Midlet; + this.mRecordStoreName = recordStoreName; + this.mHashtable = new Hashtable(); + load(); + } + + public String get(String key) { + return (String)mHashtable.get(key); + } + + public void put(String key, String value) { + if (value == null) value = ""; + mHashtable.put(key, value); + } + + private void load() throws RecordStoreException { + RecordStore rs = null; + RecordEnumeration re = null; + + try { + rs = RecordStore.openRecordStore(mRecordStoreName, true); + re = rs.enumerateRecords(null, null, false); + while (re.hasNextElement()) { + byte[] raw = re.nextRecord(); + String pref = new String(raw); + // Parse out the name. + int index = pref.indexOf('|'); + String name = pref.substring(0, index); + String value = pref.substring(index + 1); + put(name, value); + } + } + finally { + if (re != null) re.destroy(); + if (rs != null) rs.closeRecordStore(); + } + } + + public void save() throws RecordStoreException { + RecordStore rs = null; + RecordEnumeration re = null; + try { + rs = RecordStore.openRecordStore(mRecordStoreName, true); + re = rs.enumerateRecords(null, null, false); + + // First remove all records, a little clumsy. + while (re.hasNextElement()) { + int id = re.nextRecordId(); + rs.deleteRecord(id); + } + + // Now save the preferences records. + Enumeration keys = mHashtable.keys(); + while (keys.hasMoreElements()) { + String key = (String)keys.nextElement(); + String value = get(key); + String pref = key + "|" + value; + byte[] raw = pref.getBytes(); + rs.addRecord(raw, 0, raw.length); + } + } + finally { + if (re != null) re.destroy(); + if (rs != null) rs.closeRecordStore(); + } + } + +} + diff --git a/phoneClients/javaMe/dist/GpsTracker.jad b/phoneClients/javaMe/dist/GpsTracker.jad new file mode 100644 index 0000000..fec3188 --- /dev/null +++ b/phoneClients/javaMe/dist/GpsTracker.jad @@ -0,0 +1,8 @@ +MIDlet-1: GpsTracker, , com.websmithing.gpstracker.GpsTracker +MIDlet-Jar-Size: 12990 +MIDlet-Jar-URL: GpsTracker.jar +MIDlet-Name: GpsTracker +MIDlet-Vendor: Vendor +MIDlet-Version: 1.0 +MicroEdition-Configuration: CLDC-1.1 +MicroEdition-Profile: MIDP-2.1 diff --git a/phoneClients/javaMe/dist/nbrun3504791845681826142/GpsTracker.jad b/phoneClients/javaMe/dist/nbrun3504791845681826142/GpsTracker.jad new file mode 100644 index 0000000..fec3188 --- /dev/null +++ b/phoneClients/javaMe/dist/nbrun3504791845681826142/GpsTracker.jad @@ -0,0 +1,8 @@ +MIDlet-1: GpsTracker, , com.websmithing.gpstracker.GpsTracker +MIDlet-Jar-Size: 12990 +MIDlet-Jar-URL: GpsTracker.jar +MIDlet-Name: GpsTracker +MIDlet-Vendor: Vendor +MIDlet-Version: 1.0 +MicroEdition-Configuration: CLDC-1.1 +MicroEdition-Profile: MIDP-2.1 diff --git a/phoneClients/javaMe/nbproject/build-impl.xml b/phoneClients/javaMe/nbproject/build-impl.xml new file mode 100644 index 0000000..da261d7 --- /dev/null +++ b/phoneClients/javaMe/nbproject/build-impl.xml @@ -0,0 +1,1250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Classpath to J2ME Ant extension library (libs.j2me_ant_ext.classpath property) is not set. For example: location of mobility/modules/org-netbeans-mobility-antext.jar file in the IDE installation directory. + Platform home (platform.home property) is not set. Value of this property should be ${platform.active.description} emulator home directory location. + Platform boot classpath (platform.bootclasspath property) is not set. Value of this property should be ${platform.active.description} emulator boot classpath containing all J2ME classes provided by emulator. + Must set src.dir + Must set build.dir + Must set dist.dir + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set preprocessed.dir + + + + + + + + + + + + + + + + + + Must set build.classes.dir + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + Must set obfuscated.classes.dir + + + + Must set obfuscated.classes.dir + Must set obfuscator.srcjar + Must set obfuscator.destjar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set preverify.classes.dir + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MicroEdition-Configuration: ${platform.configuration} + + MicroEdition-Configuration: ${platform.configuration} + + + + MicroEdition-Profile: ${platform.profile} + + MicroEdition-Profile: ${platform.profile} + + + + Must set dist.jad + + + + + + + + + + + + + + + + + + + + + + + + ${manifest.midlets}${evaluated.manifest.apipermissions}${evaluated.manifest.pushregistry}${manifest.others}${manifest.jad} + ${manifest.midlets}${evaluated.manifest.apipermissions}${evaluated.manifest.pushregistry}${manifest.others}${manifest.manifest} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Starting emulator with port number ${active.debug.port} + + + + + + + + + + + + + + + + + Starting emulator with port number ${active.debug.port} + + + + + + + + + + + + + + + + + Must set dist.javadoc.dir + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${all.configurations} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Property deployment.${deployment.method}.scriptfile not set. The property should point to an Ant script providing ${deployment.method} deployment. + + + + + + + + Classpath to Ant Contrib library (libs.ant-contrib.classpath property) is not set. + + + + + + + + + Active project configuration: @{cfg} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Property build.root.dir is not set. By default its value should be \"build\". + Property dist.root.dir is not set. By default its value should be \"dist\". + + + + + diff --git a/phoneClients/javaMe/nbproject/genfiles.properties b/phoneClients/javaMe/nbproject/genfiles.properties new file mode 100644 index 0000000..25e0ba6 --- /dev/null +++ b/phoneClients/javaMe/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +build.xml.data.CRC32=0f5fb758 +build.xml.script.CRC32=219d9ddc +build.xml.stylesheet.CRC32=9c6a911d +nbproject/build-impl.xml.data.CRC32=0f5fb758 +nbproject/build-impl.xml.script.CRC32=8bde2673 +nbproject/build-impl.xml.stylesheet.CRC32=051c3749 diff --git a/phoneClients/javaMe/nbproject/private/private.properties b/phoneClients/javaMe/nbproject/private/private.properties new file mode 100644 index 0000000..2be98fe --- /dev/null +++ b/phoneClients/javaMe/nbproject/private/private.properties @@ -0,0 +1,7 @@ +app-version.autoincrement=false +config.active= +deployment.counter=3 +deployment.number=3.0.0 +javadoc.preview=true +netbeans.user=C:\\Users\\Nick\\AppData\\Roaming\\NetBeans\\7.4 +platform.apis.defaults=JSR179-1.0,JSR256-1.2 diff --git a/phoneClients/javaMe/nbproject/private/private.xml b/phoneClients/javaMe/nbproject/private/private.xml new file mode 100644 index 0000000..79ec6ce --- /dev/null +++ b/phoneClients/javaMe/nbproject/private/private.xml @@ -0,0 +1,12 @@ + + + + + + file:/C:/Users/Nick/Documents/Visual%20Studio%202012/Projects/GpsTracker/src/com/websmithing/gpstracker/NetWorker.java + file:/C:/Users/Nick/Documents/Visual%20Studio%202012/Projects/GpsTracker/src/com/websmithing/gpstracker/GpsTracker.java + file:/C:/Users/Nick/Documents/Visual%20Studio%202012/Projects/GpsTracker/src/com/websmithing/gpstracker/GpsHelper.java + file:/C:/Users/Nick/Documents/Visual%20Studio%202012/Projects/GpsTracker/src/com/websmithing/gpstracker/RmsHelper.java + + + diff --git a/phoneClients/javaMe/nbproject/project.properties b/phoneClients/javaMe/nbproject/project.properties new file mode 100644 index 0000000..0be96a8 --- /dev/null +++ b/phoneClients/javaMe/nbproject/project.properties @@ -0,0 +1,116 @@ +abilities=MMAPI=1.2,JSR82=1.1,JSR280=1.0,JSR226=1.0,MIDP=2.1,SATSA=1.0,CLDC=1.1,JSR177=1.0,JSR179=1.0,J2MEWS=1.0,WMA=2.0,JSR172=1.0,JSR257=1.0,JSR256=1.2,OBEX=1.0,ColorScreen,JSR239=1.0,TouchScreen,JSR211=1.0,JSR234=1.0,ScreenWidth=240,JSR75=1.0,JSR184=1.1,ScreenHeight=320,ScreenColorDepth=16, +all.configurations=\ ,JavaMEPhone1 +application.args= +application.description= +application.description.detail= +application.name= +application.vendor=Vendor +build.classes.dir=${build.dir}/compiled +build.classes.excludes=**/*.java,**/*.form,**/*.class,**/.nbintdb,**/*.mvd,**/*.wsclient,**/*.vmd +build.dir=build/${config.active} +build.root.dir=build +configs.JavaMEPhone1.abilities=MMAPI=1.2,JSR82=1.1,JSR280=1.0,JSR226=1.0,MIDP=2.1,SATSA=1.0,CLDC=1.1,JSR177=1.0,JSR179=1.0,J2MEWS=1.0,WMA=2.0,JSR172=1.0,JSR257=1.0,JSR256=1.2,OBEX=1.0,ColorScreen,JSR239=1.0,TouchScreen,JSR211=1.0,JSR234=1.0,ScreenWidth=240,JSR75=1.0,JSR184=1.1,ScreenHeight=320,ScreenColorDepth=16, +configs.JavaMEPhone1.platform.active=Oracle_Java_TM__Platform_Micro_Edition_SDK_3_4 +configs.JavaMEPhone1.platform.active.description=Oracle Java(TM) Platform Micro Edition SDK 3.4 +configs.JavaMEPhone1.platform.apis=JSR239-1.0,SATSA-1.0,WMA-2.0,JSR82-1.1,JSR184-1.1,JSR280-1.0,JSR172-1.0,JSR234-1.0,OBEX-1.0,JSR179-1.0,JSR75-1.0,JSR226-1.0,JSR211-1.0,JSR257-1.0,JSR177-1.0,J2ME-WS-1.0,MMAPI-1.2,JSR256-1.2 +configs.JavaMEPhone1.platform.bootclasspath=${platform.home}/lib/jsr172_1.0.jar:${platform.home}/lib/jsr234_1.0.jar:${platform.home}/lib/jsr135_1.2.jar:${platform.home}/lib/jsr239_1.0.jar:${platform.home}/lib/jsr75_1.0.jar:${platform.home}/lib/jsr211_1.0.jar:${platform.home}/lib/jsr177_1.0.jar:${platform.home}/lib/jsr257_1.0.jar:${platform.home}/lib/jsr184_1.1.jar:${platform.home}/lib/jsr226_1.0.jar:${platform.home}/lib/jsr205_2.0.jar:${platform.home}/lib/jsr082_1.1.jar:${platform.home}/lib/jsr179_1.0.jar:${platform.home}/lib/jsr256_1.2.jar:${platform.home}/lib/jsr280_1.0.jar:${platform.home}/lib/midp_2.1.jar:${platform.home}/lib/cldc_1.1.jar +configs.JavaMEPhone1.platform.configuration=CLDC-1.1 +configs.JavaMEPhone1.platform.device=JavaMEPhone1 +configs.JavaMEPhone1.platform.profile=MIDP-2.1 +configs.JavaMEPhone1.platform.trigger=CLDC +configs.JavaMEPhone1.platform.type=UEI-1.0.1 +debug.level=debug +debugger.timeout= +deployment.copy.target=deploy +deployment.instance=default +deployment.jarurl=${dist.jar} +deployment.method=NONE +deployment.override.jarurl=false +dist.dir=dist/${config.active} +dist.jad=GpsTracker.jad +dist.jar=GpsTracker.jar +dist.javadoc.dir=${dist.dir}/doc +dist.root.dir=dist +extra.classpath= +file.reference.builtin.ks=${netbeans.user}/config/j2me/builtin.ks +filter.exclude.tests=false +filter.excludes= +filter.more.excludes=**/overview.html,**/package.html +filter.use.standard=true +jar.compress=true +javac.debug=true +javac.deprecation=false +javac.encoding=windows-1255 +javac.optimize=false +javac.source=1.3 +javac.target=1.3 +javadoc.author=false +javadoc.encoding= +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +libs.classpath= +main.class= +main.class.class=applet +manifest.apipermissions= +manifest.file=manifest.mf +manifest.is.liblet=false +manifest.jad= +manifest.manifest= +manifest.midlets=MIDlet-1: GpsTracker, , com.websmithing.gpstracker.GpsTracker\n +manifest.others=MIDlet-Vendor: Vendor\nMIDlet-Name: GpsTracker\nMIDlet-Version: 1.0\n +manifest.pushregistry= +name=GpsTracker +no.dependencies=false +nokiaS80.application.icon= +obfuscated.classes.dir=${build.dir}/obfuscated +obfuscation.custom= +obfuscation.level=0 +obfuscator.destjar=${build.dir}/obfuscated.jar +obfuscator.srcjar=${build.dir}/before-obfuscation.jar +platform.active=Oracle_Java_TM__Platform_Micro_Edition_SDK_3_4 +platform.active.description=Oracle Java(TM) Platform Micro Edition SDK 3.4 +platform.apis=JSR179-1.0,JSR256-1.2 +platform.bootclasspath=${platform.home}/lib/jsr179_1.0.jar:${platform.home}/lib/jsr256_1.2.jar:${platform.home}/lib/midp_2.1.jar:${platform.home}/lib/cldc_1.1.jar +platform.configuration=CLDC-1.1 +platform.device=JavaMEPhone1 +platform.fat.jar=true +platform.profile=MIDP-2.1 +platform.trigger=CLDC +platform.type=UEI-1.0.1 +preprocessed.dir=${build.dir}/preprocessed +preverify.classes.dir=${build.dir}/preverified +preverify.sources.dir=${build.dir}/preverifysrc +resources.dir=resources +run.cmd.options= +run.jvmargs= +run.method=STANDARD +run.security.domain=minimum +run.use.security.domain=false +savaje.application.icon= +savaje.application.icon.focused= +savaje.application.icon.small= +savaje.application.uid=TBD +savaje.bundle.base= +savaje.bundle.debug=false +savaje.bundle.debug.port= +semc.application.caps= +semc.application.icon= +semc.application.icon.count= +semc.application.icon.splash= +semc.application.icon.splash.installonly=false +semc.application.uid=E2454680 +semc.certificate.path= +semc.private.key.password= +semc.private.key.path= +sign.alias=minimal +sign.enabled=false +sign.keystore=${file.reference.builtin.ks} +src.dir=src +use.emptyapis=true +use.preprocessor=true diff --git a/phoneClients/javaMe/nbproject/project.xml b/phoneClients/javaMe/nbproject/project.xml new file mode 100644 index 0000000..ea52a38 --- /dev/null +++ b/phoneClients/javaMe/nbproject/project.xml @@ -0,0 +1,10 @@ + + + org.netbeans.modules.kjava.j2meproject + + + GpsTracker + 1.6 + + + diff --git a/phoneClients/javaMe/src/com/websmithing/gpstracker/GpsHelper.java b/phoneClients/javaMe/src/com/websmithing/gpstracker/GpsHelper.java new file mode 100644 index 0000000..2b1fc68 --- /dev/null +++ b/phoneClients/javaMe/src/com/websmithing/gpstracker/GpsHelper.java @@ -0,0 +1,164 @@ +// +// GpsHelper.java +// GpsTracker +// +// Created by Nick Fox on 12/1/13. +// Copyright (c) 2013 Nick Fox. All rights reserved. +// + +package com.websmithing.gpstracker; + + +import javax.microedition.location.*; +import java.util.Calendar; +import java.util.Date; + +public class GpsHelper implements LocationListener { + + private LocationProvider locationProvider = null; + private Coordinates oldCoordinates = null, currentCoordinates = null; + private float distance = 0; + private int azimuth = 0; + private String uploadWebsite; + private String queryString; + private GpsTracker midlet; + private int interval; + protected Calendar currentTime; + protected long sessionID; + + + public GpsHelper(GpsTracker Midlet, int Interval, String UploadWebsite){ + currentTime = Calendar.getInstance(); + sessionID = System.currentTimeMillis(); + this.midlet = Midlet; + this.interval = Interval; + this.uploadWebsite = UploadWebsite; + } + + // getting the gps location is based on an interval in seconds. for instance, + // the location is gotten once a minute, sent to the website to be stored in + // the DB (and then viewed on Google map) and used to retrieve a map tile (image) + // to be diplayed on the phone + + public void startGPS() { + if (locationProvider == null) { + createLocationProvider(); + + Thread locationThread = new Thread() { + public void run(){ + createLocationListener(); + } + }; + locationThread.start(); + } + } + + // this allows us to change how often the gps location is gotten + public void changeInterval(int Interval) { + if (locationProvider != null) { + locationProvider.setLocationListener(this, Interval, -1, -1); + } + } + + private void createLocationProvider() { + Criteria cr = new Criteria(); + + try { + locationProvider = LocationProvider.getInstance(cr); + } catch (Exception e) { + midlet.log("GPS.createLocationProvider: " + e); + } + } + + private void createLocationListener(){ + // 2cd value is interval in seconds + try { + locationProvider.setLocationListener(this, interval, -1, -1); + } catch (Exception e) { + midlet.log("GPS.createLocationListener: " + e); + } + } + + public void locationUpdated(LocationProvider provider, final Location location) { + // get new location from locationProvider + + try { + Thread getLocationThread = new Thread(){ + public void run(){ + getLocation(location); + } + }; + + getLocationThread.start(); + } catch (Exception e) { + midlet.log("GPS.locationUpdated: " + e); + } + } + + public void providerStateChanged(LocationProvider provider, int newState) {} + + private void getLocation(Location location){ + float speed = 0; + + try { + QualifiedCoordinates qualifiedCoordinates = location.getQualifiedCoordinates(); + + qualifiedCoordinates.getLatitude(); + + if (oldCoordinates == null){ + oldCoordinates = new Coordinates(qualifiedCoordinates.getLatitude(), + qualifiedCoordinates.getLongitude(), + qualifiedCoordinates.getAltitude()); + } else { + if (!Float.isNaN( qualifiedCoordinates.distance(oldCoordinates))) { + distance += qualifiedCoordinates.distance(oldCoordinates); + } + + currentCoordinates = new Coordinates(qualifiedCoordinates.getLatitude(), + qualifiedCoordinates.getLongitude(), + qualifiedCoordinates.getAltitude()); + azimuth = (int)oldCoordinates.azimuthTo(currentCoordinates); + oldCoordinates.setAltitude(qualifiedCoordinates.getAltitude()); + oldCoordinates.setLatitude(qualifiedCoordinates.getLatitude()); + oldCoordinates.setLongitude(qualifiedCoordinates.getLongitude()); + + } + + if (qualifiedCoordinates != null){ + Date d = new Date(); + + if (!Float.isNaN(location.getSpeed())) { + speed = location.getSpeed(); + } + + queryString = "?lat=" + String.valueOf(qualifiedCoordinates.getLatitude()) + + "&lng=" + String.valueOf(qualifiedCoordinates.getLongitude()) + + "&mph=" + String.valueOf((int)(speed/1609*3600)) + + "&dir=" + String.valueOf(azimuth) + + "&dis=" + String.valueOf((int)(distance/1609)) + + "&dt=" + d.toString() + + "&lm=" + location.getLocationMethod() + + "&pn=" + midlet.phoneNumber + + "&sid=" + String.valueOf(sessionID) + + "&acc=" + String.valueOf((int)(qualifiedCoordinates.getHorizontalAccuracy()*3.28)) + + "&iv=" + String.valueOf(location.isValid()) + + "&info=" + location.getExtraInfo("text/plain") + + "&zm=" + midlet.zoomLevel + + "&h=" + midlet.height + + "&w=" + midlet.width; + + // with our query string built, we create a networker object to send the + // query to our website and get the map image and update the DB + NetWorker worker = new NetWorker(midlet, uploadWebsite); + worker.getUrl(queryString); + + } + + } catch (Exception e) { + midlet.log("GPS.getLocation: " + e); + } + } +} + + + diff --git a/phoneClients/javaMe/src/com/websmithing/gpstracker/GpsTracker.java b/phoneClients/javaMe/src/com/websmithing/gpstracker/GpsTracker.java new file mode 100644 index 0000000..f30f850 --- /dev/null +++ b/phoneClients/javaMe/src/com/websmithing/gpstracker/GpsTracker.java @@ -0,0 +1,285 @@ +// +// GpsTracker.java +// GpsTracker +// +// Created by Nick Fox on 12/1/13. +// Copyright (c) 2013 Nick Fox. All rights reserved. +// + +package com.websmithing.gpstracker; + +import javax.microedition.midlet.*; +import javax.microedition.lcdui.*; +import java.util.Calendar; + +public class GpsTracker extends MIDlet implements CommandListener, ItemStateListener { + private Display display; + private Form form; + private Form zoomScreen; + private Form settingsScreen; + private Command exitCmd; + private Command saveCmd; + private Command zoomCmd; + private Command settingsCmd; + private Command backCmd; + private TextField phoneNumberTextField; + private TextField uploadWebsiteTextField; + private Gauge zoomGauge; + private StringItem zoomStringItem; + private ChoiceGroup updateIntervalCG; + private String updateInterval; + private int[] iTimes = {60, 300, 900}; + + private RmsHelper rms; + private GpsHelper gps; + + private String uploadWebsite; + private String defaultUploadWebsite = "http://www.websmithing.com/gpstracker/GetGoogleMap2.php"; + + protected String phoneNumber; + protected String zoomLevel; + protected int height, width; + protected Calendar currentTime; + protected long sessionID; + protected Image im = null; + + public GpsTracker(){ + form = new Form("GpsTracker"); + display = Display.getDisplay(this); + exitCmd = new Command("Exit", Command.EXIT, 1); + zoomCmd = new Command("Zoom", Command.SCREEN, 2); + settingsCmd = new Command("Settings", Command.SCREEN, 3); + + form.addCommand(exitCmd); + form.addCommand(zoomCmd); + form.addCommand(settingsCmd); + form.setCommandListener(this); + + display.setCurrent(form); + currentTime = Calendar.getInstance(); + sessionID = System.currentTimeMillis(); + height = form.getHeight(); + width = form.getWidth(); + + // RMS is the phone's built in storage, kind of like a database, but + // it only stores name-value pairs (like an associative array or hashtable). + // eveything is stored as a string. + getSettingsFromRMS(); + + // the phone number field is the only empty field when the application is + // first loaded. it does not have to be a phone number, it can be any string, + // but for uniqueness, it's best to use a phone number. this only has to be + // done once. + if (hasPhoneNumber()) { + startGPS(); + displayInterval(); + } + } + + public void startApp() { + if ( form != null ) { + display.setCurrent(form); + } + } + + // let the user know how often map will be updated + private void displayInterval() { + int tempTime = iTimes[Integer.parseInt(updateInterval)]/60; + + display.setCurrent(form); + form.deleteAll(); + + if (tempTime == 1) { + log("Getting map once a minute..."); + } + else { + log("Getting map every " + String.valueOf(tempTime) + " minutes..."); + } + } + + private void loadZoomScreen() { + zoomScreen = new Form("Zoom"); + zoomGauge = new Gauge("Google Map Zoom", true, 17, Integer.parseInt(zoomLevel)); + zoomStringItem = new StringItem(null, ""); + zoomStringItem.setText("Zoom level: " + zoomGauge.getValue()); + backCmd = new Command("Back", Command.SCREEN, 1); + + zoomScreen.append(zoomGauge); + zoomScreen.append(zoomStringItem); + zoomScreen.addCommand(backCmd); + zoomScreen.setItemStateListener(this); + zoomScreen.setCommandListener(this); + + display.setCurrent(zoomScreen); + } + + // this method is called every time the zoom guage changes value. the zoom level is + // reset and saved + public void itemStateChanged(Item item) { + if (item == zoomGauge) { + zoomStringItem.setText("Zoom level: " + zoomGauge.getValue()); + zoomLevel = String.valueOf(zoomGauge.getValue()); + + try { + rms.put("zoomLevel", zoomLevel); + rms.save(); + } + catch (Exception e) { + log("GPSTracker.itemStateChanged: " + e); + } + } + } + + private void loadSettingsScreen() { + settingsScreen = new Form("Settings"); + + phoneNumberTextField = new TextField("Phone number or user name", phoneNumber, 20, TextField.ANY); + uploadWebsiteTextField = new TextField("Upload website", uploadWebsite, 100, TextField.ANY); + settingsScreen.append(phoneNumberTextField); + settingsScreen.append(uploadWebsiteTextField); + + String[] times = { "1 minute", "5 minutes", "15 minutes"}; + updateIntervalCG = new ChoiceGroup("Update map how often?", ChoiceGroup.EXCLUSIVE, times, null); + updateIntervalCG.setSelectedIndex(Integer.parseInt(updateInterval), true); + settingsScreen.append(updateIntervalCG); + + saveCmd = new Command("Save", Command.SCREEN, 1); + settingsScreen.addCommand(saveCmd); + + settingsScreen.setCommandListener(this); + display.setCurrent(settingsScreen); + } + + // get the settings from the phone's storage and load 4 global variables + public void getSettingsFromRMS() { + try { + rms = new RmsHelper(this, "GPSTracker"); + + phoneNumber = rms.get("phoneNumber"); + uploadWebsite = rms.get("uploadWebsite"); + zoomLevel = rms.get("zoomLevel"); + updateInterval = rms.get("updateInterval"); + } + catch (Exception e) { + log("GPSTracker.getSettingsFromRMS: " + e); + } + + if ((uploadWebsite == null) || (uploadWebsite.trim().length() == 0)) { + uploadWebsite = defaultUploadWebsite; + } + + if ((zoomLevel == null) || (zoomLevel.trim().length() == 0)) { + zoomLevel = "12"; + } + if ((updateInterval == null) || (updateInterval.trim().length() == 0)) { + updateInterval = "1"; + } + } + + private boolean hasPhoneNumber() { + if ((phoneNumber == null) || (phoneNumber.trim().length() == 0)) { + log("Phone number required. Please go to settings."); + return false; + } + else { + return true; + } + } + + // gps is started with the update interval. the interval is the time in between + // map updates + private void startGPS() { + if (gps == null) { + gps = new GpsHelper(this, iTimes[Integer.parseInt(updateInterval)], uploadWebsite); + gps.startGPS(); + } + } + + // this is called when the user changes the interval in the settings screen + private void changeInterval() { + if (gps == null) { + startGPS(); + } + else { + gps.changeInterval(iTimes[Integer.parseInt(updateInterval)]); + } + } + + // save settings back to phone memory + private void saveSettingsToRMS() { + try { + phoneNumber = phoneNumberTextField.getString(); + uploadWebsite = uploadWebsiteTextField.getString(); + updateInterval = String.valueOf(updateIntervalCG.getSelectedIndex()); + + rms.put("phoneNumber", phoneNumber); + rms.put("uploadWebsite", uploadWebsite); + rms.put("updateInterval", updateInterval); + + rms.save(); + } + catch (Exception e) { + log("GPSTracker.saveSettings: " + e); + } + display.setCurrent(form); + } + + // this method displays the map image, it is called from the networker object + public void showMap(boolean flag) + { + if (flag == false) { + log("Map could not be downloaded."); + } + else { + ImageItem imageitem = new ImageItem(null, im, ImageItem.LAYOUT_DEFAULT, null); + + if(form.size()!= 0) { + form.set(0, imageitem); + } + else { + form.append(imageitem); + } + } + } + + public void log(String text) { + StringItem si = new StringItem(null, text); + si.setLayout(Item.LAYOUT_NEWLINE_AFTER); + form.append(si); + } + + public void commandAction(Command cmd, Displayable screen) { + if (cmd == exitCmd) { + shutDownApp(); + } + else if (cmd == saveCmd) { + saveSettingsToRMS(); + + if (hasPhoneNumber()) { + changeInterval(); + displayInterval(); + } + } + else if (cmd == settingsCmd) { + loadSettingsScreen(); + } + else if (cmd == zoomCmd) { + loadZoomScreen(); + } + else if (cmd == backCmd) { + displayInterval(); + } + } + + public void pauseApp() {} + + public void destroyApp(boolean unconditional) {} + + protected void shutDownApp() { + destroyApp(true); + notifyDestroyed(); + } +} + + + diff --git a/phoneClients/javaMe/src/com/websmithing/gpstracker/NetWorker.java b/phoneClients/javaMe/src/com/websmithing/gpstracker/NetWorker.java new file mode 100644 index 0000000..8fe5191 --- /dev/null +++ b/phoneClients/javaMe/src/com/websmithing/gpstracker/NetWorker.java @@ -0,0 +1,119 @@ +// +// NetWorker.java +// GpsTracker +// +// Created by Nick Fox on 12/1/13. +// Copyright (c) 2013 Nick Fox. All rights reserved. +// + +package com.websmithing.gpstracker; + +import javax.microedition.io.*; +import java.io.*; +import javax.microedition.lcdui.Image; + +public class NetWorker { + private GpsTracker midlet; + private String uploadWebsite; + int i = 1; + + public NetWorker(GpsTracker lbsMidlet, String UploadWebsite){ + this.midlet = lbsMidlet; + this.uploadWebsite = UploadWebsite; + } + + public void getUrl(String queryString) { + queryString = URLencodeSpaces(queryString); + String url = uploadWebsite + queryString; + HttpConnection httpConn = null; + InputStream inputStream = null; + DataInputStream iStrm = null; + ByteArrayOutputStream bStrm = null; + Image im = null; + + try{ + httpConn = (HttpConnection)Connector.open(url); + + if(httpConn.getResponseCode() == HttpConnection.HTTP_OK){ + inputStream = httpConn.openInputStream(); + iStrm = new DataInputStream(inputStream); + + byte imageData[]; + int length = (int)httpConn.getLength(); + + if(length != -1) { + imageData = new byte[length]; + iStrm.readFully(imageData); + } + else { //Length not available + bStrm = new ByteArrayOutputStream(); + int ch; + + while((ch = iStrm.read())!= -1) { + bStrm.write(ch); + } + imageData = bStrm.toByteArray(); + + } + im = Image.createImage(imageData, 0, imageData.length); + } + else { + midlet.log("NetWorker.getUrl responseCode: " + httpConn.getResponseCode()); + } + + } catch (Exception e) { + midlet.log("NetWorker.getUrl: " + e); + } + finally{ // Clean up + try{ + if(bStrm != null) + bStrm.close(); + if(iStrm != null) + iStrm.close(); + if(inputStream != null) + inputStream.close(); + if(httpConn != null) + httpConn.close(); + } + catch(Exception e){} + } + + // if we have successfully gotten a map image, then we want to display it + if( im == null) { + midlet.showMap(false); + } + else { + midlet.im = im; + midlet.showMap(true); + } + + } + + // http://forum.java.sun.com/thread.jspa?threadID=341790&messageID=1408555 + private String URLencodeSpaces(String s) + { + if (s != null) { + StringBuffer tmp = new StringBuffer(); + int i = 0; + try { + while (true) { + int b = (int)s.charAt(i++); + + if (b != 0x20) { + tmp.append((char)b); + } + else { + tmp.append("%"); + if (b <= 0xf) { + tmp.append("0"); + } + tmp.append(Integer.toHexString(b)); + } + } + } + catch (Exception e) {} + return tmp.toString(); + } + return null; + } +} diff --git a/phoneClients/javaMe/src/com/websmithing/gpstracker/RmsHelper.java b/phoneClients/javaMe/src/com/websmithing/gpstracker/RmsHelper.java new file mode 100644 index 0000000..08e624a --- /dev/null +++ b/phoneClients/javaMe/src/com/websmithing/gpstracker/RmsHelper.java @@ -0,0 +1,88 @@ +// +// RmsHelper.java +// GpsTracker +// +// Created by Nick Fox on 12/1/13. +// Copyright (c) 2013 Nick Fox. All rights reserved. +// + +package com.websmithing.gpstracker; + +import java.util.*; +import javax.microedition.rms.*; + +public class RmsHelper { + private GpsTracker midlet; + private String mRecordStoreName; + private Hashtable mHashtable; + + public RmsHelper(GpsTracker Midlet, String recordStoreName) throws RecordStoreException { + this.midlet = Midlet; + this.mRecordStoreName = recordStoreName; + this.mHashtable = new Hashtable(); + load(); + } + + public String get(String key) { + return (String)mHashtable.get(key); + } + + public void put(String key, String value) { + if (value == null) value = ""; + mHashtable.put(key, value); + } + + private void load() throws RecordStoreException { + RecordStore rs = null; + RecordEnumeration re = null; + + try { + rs = RecordStore.openRecordStore(mRecordStoreName, true); + re = rs.enumerateRecords(null, null, false); + while (re.hasNextElement()) { + byte[] raw = re.nextRecord(); + String pref = new String(raw); + // Parse out the name. + int index = pref.indexOf('|'); + String name = pref.substring(0, index); + String value = pref.substring(index + 1); + put(name, value); + } + } + finally { + if (re != null) re.destroy(); + if (rs != null) rs.closeRecordStore(); + } + } + + public void save() throws RecordStoreException { + RecordStore rs = null; + RecordEnumeration re = null; + try { + rs = RecordStore.openRecordStore(mRecordStoreName, true); + re = rs.enumerateRecords(null, null, false); + + // First remove all records, a little clumsy. + while (re.hasNextElement()) { + int id = re.nextRecordId(); + rs.deleteRecord(id); + } + + // Now save the preferences records. + Enumeration keys = mHashtable.keys(); + while (keys.hasMoreElements()) { + String key = (String)keys.nextElement(); + String value = get(key); + String pref = key + "|" + value; + byte[] raw = pref.getBytes(); + rs.addRecord(raw, 0, raw.length); + } + } + finally { + if (re != null) re.destroy(); + if (rs != null) rs.closeRecordStore(); + } + } + +} +