posted Feb 15, 2012, 3:28 AM by Michael Schollmeyer
I just started the Facebook Page for GPS Essentials. If you are a frequent user of GPS Essentials, come and join us! I'll keep on posting latest info there plus some extra stuff you will not find anywhere else. |
posted Feb 7, 2012, 1:17 AM by Michael Schollmeyer
Some people asked about the Sticky Broadcast permission that GPS Essentials requests when you install. I believe that the name of this permission has not been chosen wisely because it is a very technical one.
I'll try to explain it as less technical as I can: A broadcast is a message that some piece of an app sends to a different piece. Since GPS Essentials is a rather big app it lives in different processes and uses broadcasts to communicate. For example, when you choose a different unit in settings a broadcast will tell both the dashboard and the map to update its widgets.
Sticky broadcasts add the capability to remain there once it has been fired up by someone. For example, when you start tracking a sticky broadcast will fire up to tell everybody. Even if you open the map after you started tracking the map can still see the broadcast message to see if you are currently tracking.
Since a broadcast message can also be sent from one app to another, Android thinks it is of some security concern and better ask the user for permission.
With the lastest dev version (2.7.0) I moved some of the functionality into services and when this migration is complete, I can hopefully take the sticky broadcast permission down again.
|
posted Feb 5, 2012, 10:24 AM by Michael Schollmeyer
[
updated Feb 5, 2012, 10:26 AM
]
I spent some time looking for a good example on how to wrap a CellTable so that it can be used in the Editor Framework. Since there was none, I wrote one by myself:
package com.mictale.example.client;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.TextInputCell;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.editor.client.SimpleBeanEditorDriver;
import com.google.gwt.editor.client.adapters.HasDataEditor;
import com.google.gwt.editor.client.adapters.ListEditor;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.DefaultSelectionEventManager;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.MultiSelectionModel;
/**
* Shows how to use {@link HasDataEditor}.
*
* {@link HasDataEditor} wraps an implementation of {@link HasData}
* so that you can use it with the editor framework. This example wraps
* a {@link CellTable} but you can also use it with {@link CellList} and others.
* In this example, the {@link Driver} only implements the workflow
* for the {@link List} of persons. Usually, you will have a hierarchy
* of {@link Editor}s and one of your model classes would return the list.
* To improve reusability, consider wrapping {@link #persons}
* and {@link #editor} into a {@link Widget} that creates
* the {@link CellTable} and implements
* {@code IsEditor>>}.
*
* @author michael@mictale.com
*/
public class HasDataEditorExample implements EntryPoint {
public interface Driver extends SimpleBeanEditorDriver, ListEditor>> {
}
private final MultiSelectionModel selectionModel = new MultiSelectionModel();
private CellTable persons;
private ListEditor> editor;
private Driver driver;
public void onModuleLoad() {
final FlowPanel panel = new FlowPanel();
panel.add(persons = createList());
panel.add(new Button("Delete Selected", new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
editor.getList().removeAll(selectionModel.getSelectedSet());
}
}));
panel.add(new Button("Add New Entry", new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
editor.getList().add(new Person());
}
}));
panel.add(new Button("Save", new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
doSave();
}
}));
editor = HasDataEditor.of(persons);
RootPanel.get().add(panel);
driver = GWT.create(Driver.class);
driver.initialize(editor);
final List persons = loadPersons();
driver.edit(persons);
}
private void doSave() {
List persons = driver.flush();
StringBuilder sb = new StringBuilder();
for (Person p : persons) {
sb.append(p.toString());
sb.append("\n");
}
Window.alert(sb.toString());
}
/**
* Creates and initializes a fake model.
* @return the fake model.
*/
private List loadPersons() {
List persons = new ArrayList();
persons.add(new Person("Michael", "Schollmeyer", "michael@mictale.com"));
persons.add(new Person("Liv", "Schollmeyer", "liv@mictale.com"));
return persons;
}
/**
* Create and initialize a {@link CellList}
* @return the new list.
*/
private CellTable createList() {
CellTable list = new CellTable();
final TextInputCell cell = new TextInputCell();
list.setSelectionModel(selectionModel, DefaultSelectionEventManager. createCheckboxManager());
Column checkColumn = new Column(new CheckboxCell(true, false)) {
@Override
public Boolean getValue(Person object) {
return selectionModel.isSelected(object);
}
};
list.addColumn(checkColumn, SafeHtmlUtils.fromSafeConstant(" "));
list.setColumnWidth(checkColumn, 40, Unit.PX);
Column firstNameColumn = new Column(cell) {
@Override
public String getValue(Person item) {
return item.getFirstName();
}
};
firstNameColumn.setFieldUpdater(new FieldUpdater() {
@Override
public void update(int index, Person object, String value) {
object.setFirstName(value);
}
});
list.addColumn(firstNameColumn, "First Name");
Column lastNameColumn = new Column(cell) {
@Override
public String getValue(Person item) {
return item.getLastName();
}
};
lastNameColumn.setFieldUpdater(new FieldUpdater() {
@Override
public void update(int index, Person object, String value) {
object.setLastName(value);
}
});
list.addColumn(lastNameColumn, "Last Name");
Column emailColumn = new Column(cell) {
@Override
public String getValue(Person item) {
return item.getEmail();
}
};
emailColumn.setFieldUpdater(new FieldUpdater() {
@Override
public void update(int index, Person object, String value) {
object.setEmail(value);
}
});
list.addColumn(emailColumn, "Email");
return list;
}
/**
* The elements in the list that we use here.
*/
public static class Person {
private String firstName;
private String lastName;
private String email;
public Person() {
}
public Person(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return firstName + ", " + lastName + ", " + email;
}
}
}
|
posted Nov 15, 2011, 8:14 AM by Michael Schollmeyer
I have recently came across this article that contains some interesting numbers about the different versions of Android that people currently use. There has been a long debate about the "device fragmentation" in the Android world and how it affects security. From the perspective of somebody who maintains an app this means that a lot of time goes into maintaining compatibility that I would prefer to spend making new features. GPS Essentials is still compatible to Android 1.5 and at the time of this writing 14,336 users are running GPS Essentials on the very first public version of Android. From the perspective of somebody using one of the Android 1.5 and 1.6 devices, the new apps that lack backward compatibility just don't appear on Android Market and more and more apps just don't update any more. Not the best environment to build a solid relationship between a software company and its customers. |
posted Nov 13, 2011, 5:10 AM by Michael Schollmeyer
The first version of the Getting Started guilde is ready for download. I promised this for a while and here it is finally. |
posted Nov 13, 2011, 3:11 AM by Michael Schollmeyer
Ars Technica had a closer look onto the Maylong M-150. This is a specimen of a class of tablets currently flooding the market. I get many requests from users of GPS Essentials asking if and how GPS Essentials will perform on these devices. Well, read the test yourself . |
posted Oct 25, 2011, 5:14 AM by Michael Schollmeyer
[
updated Oct 25, 2011, 5:45 AM
]
The new release features a toolbar for map view so that you can access common functions much easier. Get it now from the download site. |
posted Oct 20, 2011, 4:54 AM by Michael Schollmeyer
If you are working on a Mac, you most probably value a well thought user interface. Here is one exception: Or maybe the intention is: Create one file to erase the disk... |
posted May 4, 2011, 10:19 AM by Michael Schollmeyer
[
updated Oct 25, 2011, 5:12 AM
]
This this the first Beta in preparation for 2.2.
The major new feature is camera capture. You can capture images from the camera now, and GPS Essentials will store a file with a lot of Exif info inside. Additionally, a waypoint will mark the picture location. I'm eager to hear how this works, especially on older devices.
|
posted Feb 26, 2011, 9:04 AM by Michael Schollmeyer
1.8 is the latest increment in the minor version number. A small change in the numbering, a big change in the dashboard: It is a virtual grid with 5x15 now and you can fling to move the visible window over it. Place widgets anywhere you like as you have more space then widgets in the current version. Another reason for this update is that still users have problems that were running GPS Essentials 1.4 or older versions. Some background info: Android silently changed the user id for GPS Essentials and with the new user id, the app cannot access the old data. The only workaround is to uninstall GPS Essentials and reinstall it. In contrary to the theories of some commenters on Android Market, this has nothing to do with ads showing up on the main menu. While 1.8 is in maintenance mode, progress on 2.0 is ongoing. The next big feature I am currently working on is tracking. There will also be minor improvements like the marker type in your exports.
|
|