Ghini / ghini.pocket

Android field data input system
GNU General Public License v3.0
3 stars 3 forks source link
android botany data-viewer

ghini.pocket

ghini.pocket is an Android data viewer and input system. You would find it handy if you want to have a quick idea of a plant species, origin, and date it entered the garden, just by scanning a plant label. It lets you correct data, take pictures, review your inventory, and check spelling and taxonomy derivations of all accepted plant genera.

ghini.pocket has one main activity, with four pages: taxonomy review, search, results, and correction. Swipe to move from one to the other. ghini.pocket also has a desktop client activity, with which to pull data from ghini.desktop, or push your updates to the desktop database.

==================================== ==================================== ==================================== .. image:: images/ghini.pocket-0.png .. image:: images/ghini.pocket-1.png .. image:: images/ghini.pocket-2.png ==================================== ==================================== ====================================

the ghini family

and the place of ghini.pocket within the family

.. image:: images/ghini-family.png

Technical Information

The program is written in Java, and only runs on Android.

There is one MainActivity, composed of several Fragments (at the time of writing it's four Fragments: taxonomy, search, results, collect).

Fragments have the role to manage the view elements, while the Activity implements callbacks, manages the internal state, passes the internal state to Fragments upon activation.

Users staying in the first three Fragments, need not worry about synchronizing with the database. Just consider ghini.pocket as a read only application, periodically export from ghini.desktop to ghini.pocket and you will be fine.

However, ghini.pocket can also be used to collect data to be imported into the ghini.desktop database. This is the role of the CollectFragment.

Consider that anything written in view elements isn't automatically persisted, so when the user swipes left or right to leave a Fragment, all that was written in the Fragment visible elements is lost and will be recovered from the database, according to the last searched plant code.

Speaking in terms of database interaction, getting into a view, that is activating a Fragment, corresponds to begining a transaction. There are two ways to close a transaction, that is either aborting or committing it. To swipe back corresponds to aborting the transaction while to activate the write button corresponds to committing it.

The only Fragment which lets users provide data is the CollectFragment. Consequently, this is the only Fragment that has a confirm button to it.

To handle this, CollectFragment has its own state, that is kept for as long as the Fragment stays active, which is committed to the global state upon confirmation, which is overwritten with the global state when the Fragment becomes active again.

Wherever we have callbacks in the Activity that need read/write access to the corresponding Fragment internal state, we have the Fragment implement FragmentWithState, an interface that exposes the internal Fragment state and offers an updateView method. (Yes, it is cumbersome, and yes, I prefer Python dynamic types, and I wish we could define this all in the XSL gui definition file.)

After you confirm your edits, ghini.pocket will save them in logs and local database, and it will show them as edited, but it will also remind you that you are looking at data containing edits which are local to your handheld device, meaning that what you now see does not necessarily match the central database. Please consider this as an alert: it is you task to import the log file in ghini.desktop, and to again export the database to ghini.pocket.

Pictures taken in the CollectFragment are saved when the user confirms the edits, and are removed and lost together with all other edits if the user swipes back to the ResultFragment, because all references to them are lost when the edits are not persisted in the logs.

The global application state contains all that the user inserted in the visible elements and that was manually persisted. In this, it just reflects the same contents as the ghini.pocket database