Smartphones und die Holzerfassung

forestNoch bis vor kurzem hieß es Smartphones und Tables im Wald seien nur ein Spielzeug. Wie soll es überhaupt gehen, die Holzmessdaten in strömendem Regen oder prallender Sonne, dazu oft noch ohne Internet zu erfassen?  Doch die Zeiten haben sich geändert. Die Geräte werden immer tauglicher für den Einsatz im Wald. Dabei müssen es nicht immer die teueren Toughbooks sein. Auch iPads und Android Geräte lassen sich durch stoßfeste und wasserdichte Cases zu einem praktischen Werkzeug bei der Holzerfassung aufrüsten.

Viele Forstbetriebe und Holzankäufer haben das Potenzial von Smartphones/Tablets bereits erkannt und integrieren diese in ihre Abläufe. Die Holzmessdaten werden nicht mehr mit Stift und Papier aufgenommen, was früher immer fehlerträchtig und lästig war, sondern werden direkt in der App (z.B. PolterApp) angegeben. Die Apps sind häufig in der Lage die Holzdaten mit einem Verwaltungssystem zu synchronisieren. Die Synchronisation erfolgt wenn die Internetverbindung vorhanden ist. Bis dahin werden Holzmessdaten auf dem Smartphone/Tablet aufbewahrt.

PolterApp ist im App-Store

PolterAppPolterApp steht ab heute bei iTunes zum Download bereit!

Endlich können nicht nur die großen Betriebe, sondern auch die kleinen Unternehmen vom Einsatz elektronischer Medien im Wald profitieren. PolterApp ist die erste App im App-Store die zu einem günstig ist. Alle Funktionen stehen ohne Einschränkungen dauerhaft umsonst zur Verfügung. Zum anderen bietet die PolterApp Flexibilität und Stärken einer Enterprise-App, welche mühelos in bestehende Infrastrukturen integriert werden kann.

Version 1.0 der PolterApp hat sicherlich noch den BETA-Charakter. Asketisches Design, ein oder anderer Schreibfehler ist das was in kürze nachgeholt wird. Viel wichtiger ist, dass die App in unmittelbarer Kommunikation mit Nutzern entsteht und alle Besonderheiten des Einsatzgebiets berücksichtigt. Das war auch der Grund, mit der PolterApp früh genug an den Start zu gehen, um möglichst viel Feedback während laufender Entwicklung zu sammeln.

In der ersten Version bietet PolterApp folgende Funktionen an:
– Übersicht über alle erfassten Polter
– Angabe der Polterbasis Daten, wie etwa Walbesitzer, Förster, Preis etc.
– Sektionsvermessung
– Unbeschränkte Anzahl an Polter-Photos
– Speichern der GPS-Koordinate mit einem Polter. Einsicht des Polters auf Google-Maps

Die Weiterentwicklung der PolterApp läuft kontinuierlich weiter. Ich freue mich auf Euer Feedback und Kommentare!

New look, new goals

field-viewI gave up my private web site i-gorod.org and now moved my internet presence to a new domain. It is not only the domain name that was changed, but also the concept. i-gorod was once a chat for the friends of mine. Afterwards I made it to a developer blog and never found time to full it with content.

igoMobile is in opposite my business card. On one hand it enlightens the projects I work on. On the other hand it will help me to maintain the contacts, extend my network and find new challenges.

Detecting incoming and outgoing calls in Android

Detecting incoming and outgoing calls in Android can be realized in several ways. One of the possibilities is to use a custom PhoneStateListener which can be attached to the TelephonyManager in your onReceive() function of the custom BroadcastReceiver. This is a “clean” way, beacause the BoradcastReceiver object is destroyed as soon as the onReceive() function is left. But if you just want to do some little stuff, you can implement your logic directly in the onReceive() function. Here how it works.

For detecting outgoing calls you need to register android.permission.PROCESS_OUTGOING_CALLS permission. The android.intent.action.NEW_OUTGOING_CALL will be broadcasted when an outgoing call is initiated. Use an extra string variable Intent.EXTRA_PHONE_NUMBER to detect the outgoing number.

For incoming call you need to register your BroadcastReceiver for the action android.intent.action.PHONE_STATE. This will be broadcasted when the phone state is changed. The receiving intent contains an extra string variable TelephonyManager.EXTRA_STATE. If this state is TelephonyManager.EXTRA_STATE_RINGING then there will be another extra string variable (! only if state = TelephonyManager.EXTRA_STATE_RINGING !). Use TelephonyManager.EXTRA_INCOMING_NUMBER to read the incoming phone number.

And now the corresponding code. In your manifest.xml add following lines for permissions:

 
 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />

Furthermore add your BroadcastReceiver:

 
<receiver android:name="YourBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE"></action>
        <action android:name="android.intent.action.NEW_OUTGOING_CALL"></action>
    </intent-filter>
</receiver>

Your code would look like this:

public class YourBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
   Bundle bundle = intent.getExtras();
   if (bundle == null)
      return;
   String phoneNumber = null;
	
   // Incoming call
   String state = bundle.getString(TelephonyManager.EXTRA_STATE);
   if ((state != null) 
        &amp;amp;&amp;amp; (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING))) {
	   phoneNumber = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);	
	   // Here: do something with the number	         
   }
   // Outgoing call
   else if (state == null) {		
      phoneNumber = bundle.getString(Intent.EXTRA_PHONE_NUMBER);
      // Here: do something with the number
   }  
 }	
}

Copy text to Clipboard in Android

Copy some text to a clipboard in Android is pretty simple. Use a code snippet below:

private void CopyNumber(String someText, Context context) {
     ClipboardManager clipMan = (ClipboardManager)context
                    .getSystemService(Context.CLIPBOARD_SERVICE);
     clipMan.setText(someText);
}

context parameter is required if you want to use the function outside Activities

Open Folder Dialog in Delphi

For as you know, Delphi does not really have a standard dialog for choosing a particular folder, like OpenFolderDialog. The function below uses ShellAPI and implements exactly the desired behaviour.

function GetFolderDialog(const ACaption: string; 
                      out ADirectory: string): boolean;
const
  BIF_NEWDIALOGSTYLE = $0040;
  BIF_NONEWFOLDERBUTTON = $0200;
 BIF_USENEWUI = BIF_NEWDIALOGSTYLE or BIF_EDITBOX;
var
  pWindowList: Pointer;
  tbsBrowseInfo: TBrowseInfo;
  pBuffer: PChar;
  iOldErrorMode: cardinal;
  pIemIDList: PItemIDList;
  pShellMalloc: IMalloc;
begin
  CoInitialize(nil);
  try
    Result := false;
    ADirectory := '''';
    FillChar(tbsBrowseInfo, sizeof(tbsBrowseInfo), 0);
    if (ShGetMalloc(pShellMalloc) = S_OK) 
                   and Assigned(pShellMalloc) then begin
      pBuffer := pShellMalloc.Alloc(MAX_PATH);
      try
        with tbsBrowseInfo do begin
          hwndOwner := Application.Handle;
          pidlRoot := nil;
         pszDisplayName := pBuffer;
          lpszTitle := PChar(ACaption);
          ulFlags := BIF_USENEWUI or 
                         BIF_RETURNONLYFSDIRS or 
                         BIF_NONEWFOLDERBUTTON;
          lParam := 0;
        end;
       pWindowList := DisableTaskWindows(0);
        iOldErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS);
        try
          pIemIDList := ShBrowseForFolder(tbsBrowseInfo);
        finally
          SetErrorMode(iOldErrorMode);
          EnableTaskWindows(pWindowList);
        end;
        Result := Assigned(pIemIDList);
        if Result then begin
          ShGetPathFromIDList(pIemIDList, pBuffer);
          pShellMalloc.Free(pIemIDList);
          ADirectory := pBuffer;
        end;
      finally
        pShellMalloc.Free(pBuffer);
     end;
    end;
  finally
    CoUninitialize;
  end;
end;

Dynamic Programming Languages

The topic of current post is a special class of high level languages that execute dynamic programm code not known to a compile time. The key advantage of such languages is that a program and its parts written once can be later modified without recompiling the code! When can this bahaviour be useful?
Dynamic languages are widely used in web development and in games development. When a clear seperation of the fuctionality and content management is required, dynamic lanugages are of great help. For example you wrote a game and it’s obviously that it would be more better to handle the multilingual dialogs and other text in your game in such a way, that when you make changes to the content you don’t need to recompile your game.
Let’s start with PHP. It is currently one of the most popular languages in the web development sphere. PHP interpreter is typically installed as a module into a webserver like Apache and executes scripts written by programmers. There is also a standalone version of PHP, that supports GUI development. Familiar evolution process is revealed by Perl. There also exist implementations as a module and as a standalone application. Perl was first time released in 1987. It partly borrows syntax and language constructions from a set of languages like C, shell (sh), AWK and Lisp.

Looking once for a dynamic language for PDAs I came across Tcl with graphical user interface toolkit Tk. The advantage of TCl/Tk is its platform independence. A program implemented in TCL/TC can be interpreted and executed on the most popular platforms like Linux, Macintosh, Windows, Windows CE etc. The only differece is look and feel of user interface components. The early versions of TCL didn”t support OOP but nowadays there are implementations supportig the advantages of OO concept.

Another dynamic language I’d like to introduce is Python. It’s a stable and a very popular multi-paradigm programming language. Python is used in such large projects as Youtube, Zope etc. Besides Python standalone version there exists  java implementation of Python called Jython and .NET integration of Python called IronPython. In these implementations one can execute pythons scripts within java or .Net programs. Unfortunately, I found out that IronPython doesn’t work in Compact Framework because annotations aren’t fully supported in CF and IronPython rely on these libraries very strong.

A good alternative to Python is Lua. There are also implementations of this interpreter for many popular platforms. Lua integration with Java is called LuaJava and the .NET version is called Lua.NET. Lua”s interpreter is very small and very quickly. Lua is often used for games creation. The most popular games implemented in Lua are: World of Warcraft, Monkey Island 4, Parkan 2 etc. Unfortunately, the documentation for Lua leaves much to be desired.

For more information on dynamic programming languages please refer to wiki article Dynamic Programming Languages. For more information on scripting languages supported in Java visit this page.