Wednesday, September 28, 2016

ITDevCon 2016 - Next Week

Hi all,
next week there will be ITDevCon2016 and I'm looking forward to it every time I read the agenda!



Here some info that I hope you appreciate as much as I did:
  • Speakers
    • 15 speakers from all over the world (from Brazil to Slovenia, from Germany to Italy)
    • Almost all the speakers are Embarcadero MVP
  • Topics
    • Last Delphi features
    • Spring4D
    • DelphiMVC framework
    • IoT
    • Delphi and Arduino Integration
    • Firebird 3.x
    • MongoDB
    • Redis
    • Web development with Delphi and most famous web framework (Angular, React)
    • Mobile development
    • Patterns and best practices (REST - Unit Testing - EDA )

There are all prerequisites to be a great conference! 
You cannot miss it !!

Saturday, June 18, 2016

Simple chat messaging system with Delphi and Firebase

Hi all,
some time ago I posted about my open source project: Firebase4Delphi. Well, Firebase was acquired by Google and in Google I/O 2016 was showed very interesting news and new features (more info here ). My project provide a REST facade to consume FIREBASE RealTime Database API.
The Firebase Realtime Database is a cloud-hosted database. Data is stored as JSON and synchronized in realtime to every connected client. When you build cross-platform apps with our iOS, Android, and JavaScript SDKs, all of your clients share one Realtime Database instance and automatically receive updates with the newest data. - Firebase Realtime Database Documentation
In my project there is a sample application about a Chat messaging system. If you enjoy Firebase program (https://console.firebase.google.com/), you are able to create your first Firebase project! See the online documentation to undestand how Firebase works.
Once you create your application you can start to use the Chat Messaging sample, it's very easy if you follow these steps:
  1. Create a clone of Firebase4Delphi project (or download it)
  2. Open Firebase4DelphiChatDemo.dproj
  3. Deploy the app on your favorite Target Platoform (Windows, Mac, Android, iOS)
  4. Once application started, put in the settings tab (Fig 1) the URL provided by Firebase Realtime Database related to your project (Fig 2) , adding the demo name "chatdemo" as REST parameter
  5. Choose a username
  6. Click Start Chat button
Fig 1:

Fig 2:

















Monday, February 29, 2016

DEB an Event Bus framework for Delphi

Hi all,
I have just started a new open source project: Delphi Event Bus a.k.a. DEB. As the title suggest DEB is an event bus framework based on publish/subscribe mechanism. It was inspired by EventBus framework for the Android platform.

How it works

DEB is designed to decouple different parts/layers of your application while still allowing them to communicate efficiently. The really exciting feature of this framework is that you can choose the delivery mode of the events: in the Main Thread or a Background thread.



Simply put the Subscribe attribute on your subscriber method you are able to receive a specific event, and by specifying the TThreadMode in attribute you can choose the context where to deliver the event.
For example, if you have to interact with the UI EventBus can deliver events in the main thread or If your subscriber does long running tasks (HTTP request), EventBus can also use background threads to avoid UI blocking. Regardless where an event was posted the EventBus will manage Thread synchronization, so you can deliver an Event in the MainThread and the subscriber will receive it on a background thread and viceversa.

Show me the code


Support

  • DEB is a 100% ObjectPascal framework so it works on VCL and Firemonkey
  • It works with DelphiXE7 and major
  • It should be works fine also on AppMethod

Currently, the project consists in a simple getting started guide, 2 great samples and a suite of unit tests. There is a lot of work to do, so any contributor is welcome. The project is hosted on github and here there is the link. I hope you are excited as much as I am about this project!

Stay tuned!

Sunday, January 10, 2016

New Delphi Demos repository

Hi all,
I have created a new repository on GitHub to keep all interesting Delphi demo that I have figured out. Here the link to repository. This is also a way to share the code with you, so it can be improved. The first project pushed is LocationSensorPatch, relative to previous post. I will put all my demo ASAP.

Saturday, January 2, 2016

Using LocationSensor on Android Service in Delphi Seattle

Hi all,
this is a very great news!
Me and my CEO (Daniele Tetibit Time Professionals) have figured out how to implement and use the LocationSensor on Android Service.
Some months ago, I found out that there is a malfunction in Delphi: If you put LocationSensor component on Android Service DM, the service crashes. So I opened an issue on the quality portal, which was recognized and classified with majority prior.
However we need to retrieve the Device position from a background Service not by a foreground Activity.
We have investigated into the code and found this mistake in System.Android.Sensors unit:
  • For the majority of the code, it is assumed that the context of Application is an Activity 
Here is the code:

FActivity := TJNativeActivity.Wrap(System.DelphiActivity)^.clazz);

The code above works fine if you are in Android Activity context, like our case. If you are in a service context though, this doesn't work (the DelphiActivity pointer is null, rightly). If there is not necessity to have a reference to the Activty, but only the context of Application, this code is to be preferred:

LContext := TJContextWrapper.Wrap(System.JavaContext);

Below you can find the System.Sensors and System.Android.Sensors units (opportunely renamed System.SensorsDD and System.Android.SensorsDD), with the fixes explained earlier (the code contains comments for any changes):
System.SensorsDD:
// about line 748
implementation
uses
  System.Variants, System.Math, System.Character,
{$IFDEF ANDROID}
  // -- patch dd
  // include the modified System.Android.SensorsDD
  System.Android.SensorsDD;
{$ENDIF ANDROID}

System.Android.SensorsDD:
...
//about line 12
uses
  // -- patch dd
  // use the modified System.SensorsDD
  System.SensorsDD;
...
// about line 70
class constructor TPermission.Create;
var
  PackageInfo: JPackageInfo;
  PackageManager: JPackageManager;
  Activity: JActivity;
  LContext: JContext;
begin
  // -- patch dd
  // Activity := TJNativeActivity.Wrap
  // (PANativeActivity(System.DelphiActivity)^.clazz)
  LContext := TJContextWrapper.Wrap(System.JavaContext);
  PackageManager := LContext.getPackageManager();
  PackageInfo := PackageManager.getPackageInfo
    (LContext.getApplicationContext.getPackageName,
    TJPackageManager.JavaClass.GET_PERMISSIONS);
  FPermissions := PackageInfo.requestedPermissions;
end;
...
// about line 100
type
  TAndroidGeocoder = class(TGeocoder)
  private type
    TGeocoderRunnable = class(TJavaLocal, JRunnable)
    private
      FCoord: TLocationCoord2D;
      FLGeocoder: JGeocoder;
    public
      constructor Create(ACoord: TLocationCoord2D; AGeocoder: JGeocoder);
      procedure run; cdecl;
    end;
  private
  class var
    FGeocoder: JGeocoder;
    // FActivity: JActivity; // -- patch dd
    FActivity: JContextWrapper; // -- patch dd
...
// about line 130
  TUIAndroidLocationSensor = class(TCustomLocationSensor)
  private
    FPermitted: Boolean;
    // FActivity: JNativeActivity; // -- patch dd
    FActivity: JContext; // -- patch dd
    FLastValue: JLocation;
    FLocationManager: JLocationManager;
    FAccuracy: TLocationAccuracy;
    FDistance: TLocationDistance;
...
// about line 1600
constructor TUIAndroidLocationSensor.Create(AManager: TSensorManager);
var
  LocationService: JObject;
begin
  inherited;
  // FActivity := TJNativeActivity.Wrap
  // (PANativeActivity(System.DelphiActivity)^.clazz); // -- patch dd
  FActivity := TJContext.Wrap(System.JavaContext); // -- patch dd
  LocationService := FActivity.getSystemService
    (TJContext.JavaClass.LOCATION_SERVICE);
  if Assigned(LocationService) then
    FLocationManager := TJLocationManager.Wrap((LocationService as ILocalObject)
      .GetObjectID);
end;
...
// about line 1630
  function RunIfPossible(var ARunnable: TLocationRunnable;
    var AListener: TLocationListener; AProviderName: JString): Boolean;
  var
    Provider: JLocationProvider;
    LHandler: JHandler;
  begin
    Result := False;
    if FLocationManager.isProviderEnabled(AProviderName) then
    begin
      if AListener = nil then
        AListener := TLocationListener.Create(Self);
      Provider := FLocationManager.getProvider(AProviderName);
      if Provider <> nil then
      begin
        ARunnable := TLocationRunnable.Create(FLocationManager, AListener,
          AProviderName);
        // FActivity.runOnUiThread(ARunnable); // --patch dd
        // -- patch dd
        // You can use post method of Handler instead runOnUiThread in this case.
        // more info here: http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html
        LHandler := TJHandler.JavaClass.init;
        LHandler.post(ARunnable);
        Result := True;
      end;
    end;
  end;
...
// about line 1830
class constructor TAndroidGeocoder.Create;
begin
  // -- patch dd
  // FActivity := TJNativeActivity.Wrap
  // (PANativeActivity(System.DelphiActivity)^.clazz);
  FActivity := TJContextWrapper.Wrap(System.JavaContext);
  FGeocoder := TJGeocoder.JavaClass.init(FActivity);
end;


Now you are able to using LocationSensor in this way:
uses
  System.SensorsDD, System.Android.SensorsDD
...
...
var
  FSensors: TSensorArray;
  Sensor: TCustomSensor;
begin
  TSensorManager.Current.Active := true;
  FSensors := TSensorManager.Current.GetSensorsByCategory(TSensorCategory.Location);

  FSensor := nil;
  for Sensor in FSensors do
  begin
    if TCustomLocationSensor(Sensor).SensorType = TLocationSensorType.GPS then
    begin
      FSensor := TCustomLocationSensor(Sensor);
      Break;
    end;
  end;

  if not Assigned(FSensor) then
    Exit; { no location sensor is available }

  { start the sensor if it is not started }
  if not FSensor.Started then
    FSensor.Start;

You can find a complete demo here. Hopefully this solution will be helpful to you the way it was for us.

P.S.
Stay tuned as because of this fix a very interesting application/project is about to see the light of day :)