Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: How to create a local Android Service streaming audio



Permlink Replies: 16 - Last Post: Feb 21, 2018 3:34 PM Last Post By: Dave Nottage
Guest
How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2018 9:49 AM
Not exactly sure where to post this, but I've got full source code of my Google Play Application "plaStreamer" available to anyone.

I know I've read many locations across the internet on issues and problems people were having programming in Delphi and I just wanted to help with this source code.

The hardest thing was trying to find a way to have Delphi "talk" to the local android service. Current source code supplied by the Embarcadero wiki did not help and caused many bugs when trying to do whats in the source code. I had to research for several weeks in trying to get this code to work by looking through many scattered source codes across the internet and in many different languages. I hope this helps people.

It shows how to create a local android service that "talks" to each other and runs in the foreground. It uses the bass library for audio streaming.

Full Source Code here: https://github.com/War3Evo/FMX.Radio

Also here is the application on google play: https://play.google.com/store/apps/details?id=com.embarcadero.plaStreamer&hl=en

It took a lot of time to figure things out since I've just started back programming using Delphi.

I have multiple Android Handheld devices, and too bad I don't have any iphones to debug code.

I would like Embarcadero to put this on their website to help others and show what else can be done with their Delphi 10.2.2 Android mobile programming software.
Dave Nottage

Posts: 1,850
Registered: 1/7/00
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2018 11:28 AM   in response to: Guest in response to: Guest
Gregory Timmons wrote:

Not exactly sure where to post this, but I've got full source code of my Google Play Application "plaStreamer"
available to anyone.

I think this is the right place.

This is awesome, thanks! It'll serve well as a reference for others. Also, thanks for making use of the Kastri Free
code.

--
Dave Nottage [MVP, TeamB]
Find hints, tips and tricks at Delphi Worlds blog: http://www.delphiworlds.com
madammar ellias

Posts: 111
Registered: 8/17/17
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2018 8:20 AM   in response to: Guest in response to: Guest
Gregory Timmons wrote:

Full Source Code here: https://github.com/War3Evo/FMX.Radio

Also here is the application on google play: https://play.google.com/store/apps/details?id=com.embarcadero.plaStreamer&hl=en

It took a lot of time to figure things out since I've just started back programming using Delphi.

I have multiple Android Handheld devices, and too bad I don't have any iphones to debug code.

I would like Embarcadero to put this on their website to help others and show what else can be done with their Delphi 10.2.2 Android mobile programming software.

very good , but there is some problems using service in Firemonkey i have used seattle in the past and also i have used KastriFree

never Survived From Crashes when ever u try to send something from host app tp its service even with your APK

here was some past test with adjustment from your project

HOST

unit mainfrm;
 
interface
 
uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.Platform, System.Messaging,
  System.Notification, System.Android.Service,
  DW.MultiReceiver.Android,
  Androidapi.JNI.GraphicsContentViewText,
  Androidapi.JNI.JavaTypes, FMX.ScrollBox, FMX.Memo;
 
type
  TMessageReceivedEvent = procedure(Sender: TObject; const Msg: string) of object;
 
  /// <summary>
  ///   Acts as a receiver of local broadcasts sent by the service
  /// </summary>
  TServiceMessageReceiver = class(TMultiReceiver)
  private
    FOnMessageReceived: TMessageReceivedEvent;
    procedure DoMessageReceived(const AMsg: string);
  protected
    procedure Receive(context: JContext; intent: JIntent); override;
    procedure ConfigureActions; override;
  public
    property OnMessageReceived: TMessageReceivedEvent read FOnMessageReceived write FOnMessageReceived;
  end;
 
 
type
  TForm3 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Panel1: TPanel;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    FReceiver: TServiceMessageReceiver;
    procedure ServiceMessageHandler(Sender: TObject; const AMsg: string);
    procedure sendamessage(Amessages: string);
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form3: TForm3;
 
const
cServiceName = 'com.embarcadero.services.mainappsrv';
cServiceMessageAction = 'com.embarcadero.services.mainapphost'; //'com.delphiworlds.action.servicemessage';
cServiceMessageParamMessage = 'message';
 
implementation
uses
Androidapi.Helpers,
Androidapi.JNI.App,
Androidapi.JNI.Net,
Androidapi.JNI.Os,
FMX.Platform.Android;
 
{$R *.fmx}
 
 
 
 
{ TServiceMessageReceiver }
 
procedure TServiceMessageReceiver.ConfigureActions;
begin
  // Adds the appropriate action to the intent filter so that messages are received
  IntentFilter.addAction(StringToJString(cServiceMessageAction));
end;
 
procedure TServiceMessageReceiver.DoMessageReceived(const AMsg: string);
begin
  if Assigned(FOnMessageReceived) then
    FOnMessageReceived(Self, AMsg);
end;
 
procedure TServiceMessageReceiver.Receive(context: JContext; intent: JIntent);
begin
  // Retrieves the message from the intent
  DoMessageReceived(JStringToString(intent.getStringExtra(StringToJString(cServiceMessageParamMessage))));
end;
 
 
procedure TForm3.Button1Click(Sender: TObject);
var
LIntent: JIntent;
Data: Jnet_Uri;
begin
LIntent := TJIntent.Create;
LIntent.setClassName(TAndroidHelper.Context.getPackageName(),
TAndroidHelper.StringToJString(cServiceName));
 
Data := TJnet_Uri.JavaClass.parse(StringToJString('You whats up ?'));
LIntent.setData(Data);
 
LIntent.setAction(StringToJString('SENDCMD'));
 
TAndroidHelper.Activity.startService(LIntent);    //crash after sent
 
end;
 
 
 
procedure TForm3.Button2Click(Sender: TObject);
begin
sendamessage('StopIntent');
end;
 
procedure TForm3.FormCreate(Sender: TObject);
var
  LIntent: JIntent;
  Data: Jnet_Uri;
begin
FReceiver := TServiceMessageReceiver.Create(True);
FReceiver.OnMessageReceived := ServiceMessageHandler;
 
LIntent := TJIntent.Create;
LIntent.setClassName(TAndroidHelper.Activity.getBaseContext,
TAndroidHelper.StringToJString(cServiceName));
Data := TJnet_Uri.JavaClass.parse(StringToJString('Hi there'));
LIntent.setData(Data);
LIntent.setAction(StringToJString('StartIntent'));
TAndroidHelper.Activity.startService(LIntent);
 
end;
 
 
procedure TForm3.FormDestroy(Sender: TObject);
begin
  FReceiver.Free;
  inherited;
end;
 
 
procedure TForm3.sendamessage(Amessages: string);
var
  LIntent: JIntent;
begin
 
LIntent := TJIntent.Create;
LIntent.setClassName(TAndroidHelper.Context.getPackageName(),
TAndroidHelper.StringToJString(cServiceName));
LIntent.setAction(StringToJString(Amessages));
TAndroidHelper.Activity.startService(LIntent);
 
end;
 
procedure TForm3.ServiceMessageHandler(Sender: TObject; const AMsg: string);
begin
Memo1.Lines.Add(AMsg);
end;
 
end.


Service

unit servfrm;
 
interface
 
uses
  System.SysUtils,
  System.Classes,
  System.Android.Service,
  System.Notification,
  Androidapi.JNI.Support,
  Androidapi.Helpers,
  AndroidApi.JNI.GraphicsContentViewText,
  Androidapi.JNI.Os,
  DW.Androidapi.JNI.LocalBroadcastManager;
 
type
  TAndroidServiceDM = class(TAndroidService)
    function AndroidServiceStartCommand(const Sender: TObject;
      const Intent: JIntent; Flags, StartId: Integer): Integer;
  private
    procedure DoMessage(const AMsg: string);
    procedure DOSTARTINTENT(Const Amsg : string);
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  AndroidServiceDM: TAndroidServiceDM;
 
const
  cServiceMessageAction = 'com.embarcadero.services.mainapphost'; // Your Main Application
  cServiceMessageParamMessage = 'message';
 
implementation
 
uses
  Androidapi.JNI.App,
  Androidapi.JNI.JavaTypes;
 
 
 
{%CLASSGROUP 'FMX.Controls.TControl'}
 
{$R *.dfm}
 
function TAndroidServiceDM.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
// recieve commands
if Assigned(Intent) then
begin
 
if Intent.getAction.equalsIgnoreCase(StringToJString('StopIntent')) = true then
begin
JavaService.stopSelf;
Result := TJService.JavaClass.START_NOT_STICKY;
end
 
else if Intent.getAction.equalsIgnoreCase(StringToJString('StartIntent')) = true then
begin
DOSTARTINTENT(JStringToString(Intent.getData.toString));
Result := TJService.JavaClass.START_STICKY;
end
 
else if Intent.getAction.equalsIgnoreCase(StringToJString('SENDCMD')) = true then
begin
DOSTARTINTENT(JStringToString(Intent.getData.toString));
Result := TJService.JavaClass.START_STICKY;
 
end;
 
 
 
end;
 
 
end;
 
procedure TAndroidServiceDM.DOSTARTINTENT(Const Amsg : string);
begin
DoMessage(Amsg);
end;
 
 
 
procedure TAndroidServiceDM.DoMessage(const AMsg: string);
var
  LIntent: JIntent;
begin
LIntent := TJIntent.JavaClass.init(StringToJString(cServiceMessageAction));
//LIntent.putExtra(StringToJString(cServiceMessageParamMessage), StringToJString(GetLogTime + ':' + AMsg));
LIntent.putExtra(StringToJString(cServiceMessageParamMessage), StringToJString(AMsg));
TJLocalBroadcastManager.JavaClass.getInstance(TAndroidHelper.Context).sendBroadcast(LIntent);
end;
 
 
 
 
end.


when ever i do SENDCMD "LIntent.setAction(StringToJString('SENDCMD'));" from host app to service app got crashed and closed with force close message in monitor
Guest
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2018 9:37 AM   in response to: madammar ellias in response to: madammar ellias
Does my APK work without modifications for you? If not, it could be your version of Delphi isn't compatible with mine. I did notice that I've had to make changes from version 10.1 to 10.2 in my Delphi code as the code wasn't compatible from 10.1 to 10.2. So just that little difference between Delphi versions could be the issue. If that is the case, you'll have to find a work around for yourself on that version of Delphi you have.

other reasons I think there could be an issue...

What version of android are you debugging on and what version of Delphi?

I used Delphi 10.2.2 and Android 6.0.1 to debug. The apk from google play works on all my android phones... versions 6.0.1, 7.0, and 8.0.

I've also learned that sometimes before you rebuild your service or main app, you need to delete debug and release folders and rebuild. Delphi doesn't seem to completely clean up the debug / release folders and can cause issues.

Edited by: Gregory Timmons on Feb 19, 2018 10:20 AM
madammar ellias

Posts: 111
Registered: 8/17/17
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2018 10:43 AM   in response to: Guest in response to: Guest
Gregory Timmons wrote:
Does my APK work without modifications for you? If not, it could be your version of Delphi isn't compatible with mine. I did notice that I've had to make changes from version 10.1 to 10.2 in my Delphi code as the code wasn't compatible from 10.1 to 10.2. So just that little difference between Delphi versions could be the issue. If that is the case, you'll have to find a work around for yourself on that version of Delphi you have.

other reasons I think there could be an issue...

What version of android are you debugging on and what version of Delphi?

I used Delphi 10.2.2 and Android 6.0.1 to debug. The apk from google play works on all my android phones... versions 6.0.1, 7.0, and 8.0.

I've also learned that sometimes before you rebuild your service or main app, you need to delete debug and release folders and rebuild. Delphi doesn't seem to completely clean up the debug / release folders and can cause issues.

i tested on delphi Seattle , Tested on Samsung J3 which android version is 6.0.1 & Galaxy J7 and S8 as well when ever i press the button to send command to the service app force closes , in your radio apk app when ever i click pause the app got crashed .
Guest
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2018 11:28 AM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:
Gregory Timmons wrote:
Does my APK work without modifications for you? If not, it could be your version of Delphi isn't compatible with mine. I did notice that I've had to make changes from version 10.1 to 10.2 in my Delphi code as the code wasn't compatible from 10.1 to 10.2. So just that little difference between Delphi versions could be the issue. If that is the case, you'll have to find a work around for yourself on that version of Delphi you have.

other reasons I think there could be an issue...

What version of android are you debugging on and what version of Delphi?

I used Delphi 10.2.2 and Android 6.0.1 to debug. The apk from google play works on all my android phones... versions 6.0.1, 7.0, and 8.0.

I've also learned that sometimes before you rebuild your service or main app, you need to delete debug and release folders and rebuild. Delphi doesn't seem to completely clean up the debug / release folders and can cause issues.

i tested on delphi Seattle , Tested on Samsung J3 which android version is 6.0.1 & Galaxy J7 and S8 as well when ever i press the button to send command to the service app force closes , in your radio apk app when ever i click pause the app got crashed .

I guess my source code does not work for Delphi Seattle and I'll make a note on the GitHub that one user has found that this source code is incompatible with Delphi Seattle. If you can figure out a fix for Delphi Seattle, let me know and I'll update the github with your work around instructions.

Edited by: Gregory Timmons on Feb 19, 2018 11:33 AM
madammar ellias

Posts: 111
Registered: 8/17/17
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2018 12:05 PM   in response to: Guest in response to: Guest
Gregory Timmons wrote:

I guess my source code does not work for Delphi Seattle and I'll make a note on the GitHub that one user has found that this source code is incompatible with Delphi Seattle. If you can figure out a fix for Delphi Seattle, let me know and I'll update the github with your work around instructions.

this is not seattle compatibility issue , i have tested "your apk on the playstore" with same result clicking on pause make the app crash force closd i think its an issue in start command but i dont see any thing can cause that maybe more exprets can help in this . my source is posted above simple service with strings sharing using ..
Guest
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2018 1:22 PM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:
Gregory Timmons wrote:

I guess my source code does not work for Delphi Seattle and I'll make a note on the GitHub that one user has found that this source code is incompatible with Delphi Seattle. If you can figure out a fix for Delphi Seattle, let me know and I'll update the github with your work around instructions.

this is not seattle compatibility issue , i have tested "your apk on the playstore" with same result clicking on pause make the app crash force closd i think its an issue in start command but i dont see any thing can cause that maybe more exprets can help in this . my source is posted above simple service with strings sharing using ..

So then it's your phone. I'll upload a video of all 4 phones I have with no issues later tonight. Galaxy tablet, Galaxy S8+, Moto play 4, and Moto Z2 Force installs and plays with no issues.

It may crash if your phone doesn't have internet for my apk on Google play. I think I should test if someone has internet or not before trying to connect.

Edited by: Gregory Timmons on Feb 19, 2018 1:22 PM

I was thinking of creating this as a component for both the service and main app.... So maybe I'll do that as a fresh start. Try and figure out what your issue maybe? Sorry I can't seem to figure it out right now.

Edited by: Gregory Timmons on Feb 19, 2018 1:26 PM

Can someone else verify if my code works for them or not?

Edited by: Gregory Timmons on Feb 19, 2018 1:39 PM
madammar ellias

Posts: 111
Registered: 8/17/17
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2018 8:27 AM   in response to: Guest in response to: Guest
Gregory Timmons wrote:
So then it's your phone. I'll upload a video of all 4 phones I have with no issues later tonight. Galaxy tablet, Galaxy S8+, Moto play 4, and Moto Z2 Force installs and plays with no issues.

It may crash if your phone doesn't have internet for my apk on Google play. I think I should test if someone has internet or not before trying to connect.

Edited by: Gregory Timmons on Feb 19, 2018 1:22 PM

I was thinking of creating this as a component for both the service and main app.... So maybe I'll do that as a fresh start. Try and figure out what your issue maybe? Sorry I can't seem to figure it out right now.

i dont see any sense of So then it's your phone. and who says it does not works ? it is working as playing audio if that what you mean , but sending pause to service will crash your APP ! its not your app issue neither your coding issue it is a firemonkey service issue i have other application that uses service that i developed under other ide and it does NOT have all of this problems while communicating between host app and its service callsub do every thing smoothly .

i dont see what is hard in the code that i provide to make it clear to you that its not coding issue its Firemonkey issue no matter how hard you try to adjust code it will fail on some devices .
Guest
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2018 9:13 AM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:
Gregory Timmons wrote:
So then it's your phone. I'll upload a video of all 4 phones I have with no issues later tonight. Galaxy tablet, Galaxy S8+, Moto play 4, and Moto Z2 Force installs and plays with no issues.

It may crash if your phone doesn't have internet for my apk on Google play. I think I should test if someone has internet or not before trying to connect.

Edited by: Gregory Timmons on Feb 19, 2018 1:22 PM

I was thinking of creating this as a component for both the service and main app.... So maybe I'll do that as a fresh start. Try and figure out what your issue maybe? Sorry I can't seem to figure it out right now.

i dont see any sense of So then it's your phone. and who says it does not works ? it is working as playing audio if that what you mean , but sending pause to service will crash your APP ! its not your app issue neither your coding issue it is a firemonkey service issue i have other application that uses service that i developed under other ide and it does NOT have all of this problems while communicating between host app and its service callsub do every thing smoothly .

i dont see what is hard in the code that i provide to make it clear to you that its not coding issue its Firemonkey issue no matter how hard you try to adjust code it will fail on some devices .

Okay, welp. I'm not a coding expert, so I'm not able to completely solve this issue. Maybe a new set of eyes can help us. I'm just a hobbyist programmer.
Dave Nottage

Posts: 1,850
Registered: 1/7/00
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2018 11:28 AM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

never Survived From Crashes when ever u try to send something from host app tp its service even with your APK

How are you "sending" something? I show the code that you're using to do this.

--
Dave Nottage [MVP, TeamB]
Find hints, tips and tricks at Delphi Worlds blog: http://www.delphiworlds.com
madammar ellias

Posts: 111
Registered: 8/17/17
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2018 11:56 AM   in response to: Dave Nottage in response to: Dave Nottage
Dave Nottage wrote:

How are you "sending" something? I show the code that you're using to do this.

--
Dave Nottage [MVP, TeamB]
Find hints, tips and tricks at Delphi Worlds blog: http://www.delphiworlds.com

the full code is above, any way

procedure TForm3.Button1Click(Sender: TObject);
var
LIntent: JIntent;
Data: Jnet_Uri;
begin
LIntent := TJIntent.Create;
LIntent.setClassName(TAndroidHelper.Context.getPackageName(),
TAndroidHelper.StringToJString(cServiceName));
 
Data := TJnet_Uri.JavaClass.parse(StringToJString('You whats up ?'));// send something
LIntent.setData(Data);
 
LIntent.setAction(StringToJString('SENDCMD'));
 
TAndroidHelper.Activity.startService(LIntent);    //crash after sent
 
end;
Dave Nottage

Posts: 1,850
Registered: 1/7/00
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2018 12:06 PM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

the full code is above, any way

procedure TForm3.Button1Click(Sender: TObject);
var
LIntent: JIntent;
Data: Jnet_Uri;
begin
LIntent := TJIntent.Create;
LIntent.setClassName(TAndroidHelper.Context.getPackageName(),
TAndroidHelper.StringToJString(cServiceName));
 
Data := TJnet_Uri.JavaClass.parse(StringToJString('You whats up ?'));// send something
LIntent.setData(Data);
 
LIntent.setAction(StringToJString('SENDCMD'));
 
TAndroidHelper.Activity.startService(LIntent);    //crash after sent
 
end;

..and exactly what happens when the app crashes? e.g. are you running it in the IDE? If so, does the Debugger Exception
Notifier appear, and what Call Stack is showing when you click "Break"?

In any event, this might not be the best method to "send messages" to the service from the app. There are other ways;
the foremost one being to "bind" to the service. I'll update the demo in the Kastri Free project to include this.

--
Dave Nottage [MVP, TeamB]
Find hints, tips and tricks at Delphi Worlds blog: http://www.delphiworlds.com
madammar ellias

Posts: 111
Registered: 8/17/17
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2018 2:37 PM   in response to: Dave Nottage in response to: Dave Nottage
Dave Nottage wrote:

..and exactly what happens when the app crashes? e.g. are you running it in the IDE? If so, does the Debugger Exception
Notifier appear, and what Call Stack is showing when you click "Break"?

In any event, this might not be the best method to "send messages" to the service from the app. There are other ways;
the foremost one being to "bind" to the service. I'll update the demo in the Kastri Free project to include this.

--
Dave Nottage [MVP, TeamB]
Find hints, tips and tricks at Delphi Worlds blog: http://www.delphiworlds.com

The debugger terminated as it maye the application got closed and by running the monitor i see force closed message
Dave Nottage

Posts: 1,850
Registered: 1/7/00
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2018 11:06 PM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

The debugger terminated as it maye the application got closed and by running the monitor i see force closed message

Again: Are you running it from the IDE? Also, if you're using Monitor, you'll be able to see why the OS forced it
closed.

I've updated the demo:

https://github.com/DelphiWorlds/KastriFree/tree/master/Demos/AndroidLocation

Namely these two units:

https://github.com/DelphiWorlds/KastriFree/blob/master/Demos/AndroidLocation/Application/LA.MainFrm.pas
https://github.com/DelphiWorlds/KastriFree/blob/master/Demos/AndroidLocation/Service/LS.ServiceModule.pas

To demonstrate how to "bind" to a service, and therefore access it direct rather than by "sending messages"; which is
not really what your code does anyway: you're using startService to give it an intent with different "commands". That's
overkill.

--
Dave Nottage [MVP, TeamB]
Find hints, tips and tricks at Delphi Worlds blog: http://www.delphiworlds.com
madammar ellias

Posts: 111
Registered: 8/17/17
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2018 2:18 PM   in response to: Dave Nottage in response to: Dave Nottage
Dave Nottage wrote:
I've updated the demo:

https://github.com/DelphiWorlds/KastriFree/tree/master/Demos/AndroidLocation

Namely these two units:

https://github.com/DelphiWorlds/KastriFree/blob/master/Demos/AndroidLocation/Application/LA.MainFrm.pas
https://github.com/DelphiWorlds/KastriFree/blob/master/Demos/AndroidLocation/Service/LS.ServiceModule.pas

To demonstrate how to "bind" to a service, and therefore access it direct rather than by "sending messages"; which is
not really what your code does anyway: you're using startService to give it an intent with different "commands". That's
overkill.

--
Dave Nottage [MVP, TeamB]
Find hints, tips and tricks at Delphi Worlds blog: http://www.delphiworlds.com

i stay 2 hours look at the demo i don't see any where you send any message to service . the code that i provided is very simple to understand for sharing strings without complex on some phone it has problems and some phones it works .

maybe it will help other delphi developers sense i am not using Firemonkey anymore just for knowledge i were interested to this topic hope good luck for others who find this kind of topics is helpful for Firemonkey service usage . Thanks you for your efforts any how its good demo .
Dave Nottage

Posts: 1,850
Registered: 1/7/00
Re: How to create a local Android Service streaming audio
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2018 3:34 PM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

i stay 2 hours look at the demo i don't see any where you send any message to service . the code that i provided is
very simple to understand for sharing strings without complex on some phone it has problems and some phones it works

Please read my previous reply carefully. I did not say that I "send messages" to the service. Here's some pointers -
in LA.MainFrm.pas:

I have declared references to the service datamodule in the service, and to a TLocalServiceConnection, that allows
"binding" to the service. There is also a handler for when the app "binds" to the service (ServiceConnectedHandler),
and one for TApplicationEventMessage, which is required so that the application can bind/unbind from the service:

 
  ...   
  [Unsafe] FService: TServiceModule; // <--- This is a reference to the actual service datamodule
  FServiceConnection: TLocalServiceConnection;
  procedure ApplicationEventMessageHandler(const Sender: TObject; const M: TMessage);
  ...
  procedure ServiceConnectedHandler(const ALocalService: TAndroidBaseService);  // <--- Event called once the service
is connected


In the constructor, the FServiceConnection is created, the OnConnected handler assigned, the service started, and the
message subscribed to:

  ...
  FServiceConnection := TLocalServiceConnection.Create;
  FServiceConnection.OnConnected := ServiceConnectedHandler;
  FServiceConnection.StartService('LocationService');
  TMessageManager.DefaultManager.SubscribeToMessage(TApplicationEventMessage, ApplicationEventMessageHandler); 
  ...


In the message event handler, when the app becomes active, it "binds" to the service, and when it enters the
background, the app "unbinds" from the service.

  ...
  case TApplicationEventMessage(M).Value.Event of
    TApplicationEvent.BecameActive:
      // Bind the service, so an reference to the service datamodule can be obtained
      FServiceConnection.BindService('LocationService');
    TApplicationEvent.EnteredBackground:
    begin
      // Make sure to "unbind" when the app becomes inactive!
      FServiceConnection.UnbindService;
      FService := nil;
    end;
  end;
  ...


In ServiceConnectedHandler, which is when the app successfully "binds" to the service, it obtains a reference to the
service datamodule:

  procedure TfrmMain.ServiceConnectedHandler(const ALocalService: TAndroidBaseService);
  begin
    // Obtain a reference to the service datamodule
    FService := TServiceModule(ALocalService);
  end;


Now the application has direct access to the service datamodule, so it does not need to "send messages". You can see
in the PauseUpdateActionsExecute method that the app is accessing the service datamodule direct, and calling methods
and properties on it (i.e. IsPaused property, Pause and Resume methods):

  procedure TfrmMain.PauseUpdatesActionExecute(Sender: TObject);
  begin
    if FService <> nil then
    begin
      if FService.IsPaused then
        FService.Resume
      else
        FService.Pause;
    end;
  end;


This is not complex. Whether or not this will have problems on the devices you're using I couldn't say because I don't
have any of them.

If the app itself is "crashing", and you're running it from the IDE, the IDE should stop with a Debugger Exception
Notification window. When that appears, there's a "Break" button. With the default IDE settings, when Break is clicked,
the Call Stack window is shown. Being able to interpret the Call Stack (or having someone who can) is crucial to
solving these kinds of problems. Knowing how to properly use Monitor or other logcat viewer also goes a long way.

--
Dave Nottage [MVP, TeamB]
Find hints, tips and tricks at Delphi Worlds blog: http://www.delphiworlds.com
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02