0

I know how to send data to a remote background android service:

.
.
FServiceConnection: TRemoteServiceConnection;
.
.
procedure TForm1.Button1Click(Sender: TObject);
const
  GET_STRING = 1234;
var
  LMessage: JMessage;
begin
  FServiceConnection := TRemoteServiceConnection.Create;
  FServiceConnection.BindService('Name of the APK containing service', 'Service name');

  LMessage := TJMessage.JavaClass.obtain(nil, GET_STRING);
  LMessage.replyTo := FServiceConnection.LocalMessenger;
  FServiceConnection.ServiceMessenger.send(LMessage);
end;

But how do the same for local android service?

.
.
FServiceConnection: TLocalServiceConnection;
.
.
procedure TForm1.Button1Click(Sender: TObject);
const
  GET_STRING = 1234;
var
  LMessage: JMessage;
begin
  FServiceConnection := TLocalServiceConnection.Create;
  FServiceConnection.BindService('Service name');

  LMessage := TJMessage.JavaClass.obtain(nil, GET_STRING);
  ????
  ????
end;

Or is there another way to send messages between application and background android local service?

Advise someone of you with this problem?

KJAN
  • 227
  • 4
  • 15

3 Answers3

1

I make it with ServiceStartCommand event in my Android Local Service.

Press button on the HOST application activity to send into the service a 'start command' wraped in a JIntent.

procedure TForm3.Button1Click(Sender: TObject);
var
  LIntent: JIntent;
begin
  Log.D('Try to start');
  LIntent := TJIntent.Create;
  LIntent.setClassName(TAndroidHelper.Context.getPackageName(),
    TAndroidHelper.StringToJString('com.embarcadero.services.SvcTimer'));
  LIntent.setAction(StringToJString('StartIntent'));
  TAndroidHelper.Activity.startService(LIntent);
end;

The service gets a command and tests my JIntent, what have to do with one.

function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent;
  Flags, StartId: Integer): Integer;
begin
  Log('+ START with Intent: ' + JStringToString(Intent.getAction.toString), []);
  if Intent.getAction.equalsIgnoreCase(StringToJString('StopIntent')) then
  begin
    Log('... service to be stoped', []);
...
    JavaService.stopSelf;
    Result := TJService.JavaClass.START_NOT_STICKY; // don't reload service
    Log('- service stoped', []);
  end
  else if Intent.getAction.equalsIgnoreCase(StringToJString('StartIntent')) then
  begin
...
    LocationSensor.Active := True;
    Result := TJService.JavaClass.START_STICKY; // rerun service if it stops
    Log('+ Service started', []);
  end;
end;

So on we execute the host application commands.

Pax Beach
  • 2,059
  • 1
  • 20
  • 27
1

Actually you can send message to a local service. The answer that Pax Beach shows will crash my service, but if I simply do what I did bellow it will work very fine:

function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
  if (JStringToString(Intent.getAction) = 'StopIntent') then
  begin
       Result := TJService.JavaClass.START_NOT_STICKY;
       JavaService.stopSelf;
       Exit;
  end;
  (....)
end;
Magno
  • 387
  • 4
  • 13
-3

It´s not possible to Handle Messages in LocalServices... only in Remote Services.

See: http://pt.slideshare.net/jimmckeeth/creating-android-services-with-delphi-and-rad-studio-10-seattle