LoginSignup
4
2

More than 3 years have passed since last update.

Android の StartService のアプリを Delphi で作ってみた

Last updated at Posted at 2018-08-29

Android にはバッググラウンドで UI 無しで動作するサービスという仕組みがあります

スレッドはアプリケーションが動作している間だけ、裏で別の作業を行なうのですが、サービスはアプリケーションが動作していないときでも独立して裏で動作することができます

Android Developer の Android Service のドキュメントを読むと、サービスには StartService と BindService の2種類があります

StartService - アプリケーションによって開始され、実行(処理)が完了した際には、自身で停止する必要がある
BindService - 他から使われている限り実行し続け、誰からも使われなくなったら、サービスを破棄する

この記事では StartService を使ったアプリを Delphi で作ります
使用したのは RAD Studio で、バージョンは 10.2.3 Tokyo Enterprise Edition です
もちろん Delphi の Community Edition でも作成できます

どんなアプリを作るの?

アプリ側でボタンを押したらサービスが起動するアプリ
サービス側では通知を行い StartService なので、自身で停止します
Android の通知については、Delphi で Android Notification (通知) をご参照くださいませ

作成の手順は
1. メインのアプリの画面を作成する
2. サービスを作成する
3. メイン側にサービスを呼び出す処理を追加する
4. メイン側のアプリにサービスを追加する
5. アプリを実行する
です

メインのアプリの画面を作成する

新規アプリケーションを作成して、ボタンを配置するだけの簡単なお仕事
service02.png

サービスを作成する

プロジェクトグループに追加という形で作成します

1. 上記のメインの設計画面が表示されている状態で、プロジェクトマネージャ上で、プロジェクトグループ名(ProjectGroup1など)を選択して、マウスの右ボタンをクリックします

表示されたポップアップメニューから「新規プロジェクトを追加」を選択します
service01.png

2. 表示された新規作成のダイアログ上で、Delphi プロジェクトの Android サービスを選択して[OK]ボタンをクリックします

service04.png

3. Android サービスのダイアログが表示されます

ローカルサービスを選択して [OK]ボタンをクリックします
service05.png

4. 新しいプロジェクトが追加されます

追加されたプロジェクトのユニットファイル(ここでは Unit2)のタブをクリックして、設計画面にします

5. 画面上はデータモジュールのようなコンテナ画面(TDM: TAndroidService)で、今回は通知を行なうので、ここに非ビジュアルコンポーネントである TNotificationCenter コンポーネントをツールパレットからドラックアンドドロップして貼り付けます

service03.png

6. コンテナである DM(TDM) の OnStartCommand のイベントにサービスが起動された際の処理を記述します

また StartService なので、自身で停止するコードも記述します

// uses に Androidapi.Jni.app を追加すること
function TDM.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: Integer): Integer;
var
  mNotice: TNotification;
begin
  // サービスの開始
  Sleep(15000);  // 15秒待ってから通知する

  // 通知
  mNotice := NotificationCenter1.CreateNotification;
  mNotice.Title := 'サービスから通知';
  mNotice.AlertBody := 'チュミミーン';
  NotificationCenter1.PresentNotification(mNotice);

  // 自身で終了
  JavaService.stopSelf;

  // StartService は result を返す
  Result := TJService.JavaClass.START_NOT_STICKY;
  mNotice.DisposeOf;
end;

15 秒待たせたのは、単にサービスが動いていることを証明するスクショを取りたかっただけですw

7. すべて保存して、ビルドを行なっておきます (実行ではない)

サービス側はコレで完了です

メイン側にサービスを呼び出す処理を追加する

設計画面の Unit1 側のタブをクリックして、メイン側に切り替えておきます

1. サービスのユニットをメイン側に追加する

メニューから「ファイル|使用するユニット」を選択
service06.png

unit2 を選択して「OK」をクリックします
service07.png

2. Button1 の OnClick イベントにサービスを呼び出す処理を記述します

サービスを呼び出すために

  • uses に System.Android.Service を追加します
  • private 宣言に、TLocalServiceConnection の宣言を追加します
  • OnClick イベント内にサービスを呼び出す処理を記述します

サンプルコードは以下です

unit Unit1;

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, System.Android.Service;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private 宣言 }
    mService: TLocalServiceConnection;  // 追加
  public
    { public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

uses Unit2;

procedure TForm1.Button1Click(Sender: TObject);
begin
// uses に System.Android.Service を追加を忘れずに

// Service 起動
// StartService で指定するのはプロジェクト名で OK
  mService := TLocalServiceConnection.Create;
  mService.StartService('Project2');
end;

end.
3. 保存してビルドしてエラーが無いかを確認しておきます

メイン側もコレで完了
実行するとデバイスに配置されてしまうので、実行ではなくビルドで

メイン側のアプリにサービスを追加する

サービス側はメインのアプリと共に配布するので、メイン側にサービスを追加するという作業が必要です
これもメニューが用意されているので、容易に行うことができます
Android のマニフェストファイルへの追加も行なってくれるので便利便利

1. プロジェクトマネージャ上でメインのプロジェクトのターゲットプラットフォームの中の Android プラットフォームを選択します

マウスの右ボタンをクリックして「Android サービスの追加」を選択します
service08.png

2. 「新規 Android サービスの追加」のダイアログが表示されます

デフォルトの「プロジェクトの基底パスからファイルを自動的に検索する」を選択して「次へ」をクリックします
service09.png

3. 「Andorid サービスの選択」の画面が表示されます

サービス(ここでは Project2)のあるフォルダを選択して「次へ」をクリックします
service11.png

4. 「変更の確認」の画面が表示されます

必要なファイルが自動検索できた場合は、この画面が表示されますので「終了」をクリックします
service14.png

必要なファイルが自動検索できなかった場合は、足らない部分を喚起するダイアログが表示されます
service12.png

ので、足りなかった箇所を補って「終了」をクリックします
service13.png

注意: メイン側とサービス側を同じフォルダに保存している場合は、サービス側のプロジェクトファイル等が設定されているかを確認します(メイン側が指定されている場合がある)

これで、メイン側のアプリにサービスの追加が完了です

Android のマニフェストファイル (AndroidManifest.xml) をみてみると

service タグに、サービスのプロジェクトである com.embarcadero.services.Project2 の記述があります

<service android:name="com.embarcadero.services.Project2" android:exported="false"/>

配置されるものを確認すると

サービス追加前
service10.png

サービス追加後
service15.png

ここでも Project2 (libProject2.so)が追加されているのが分かります

アプリを実行すると

メイン側のアプリを起動して、ボタンをタップするとサービスが起動します
Screenshot_20180828-115233.png

このアプリでは 15秒経過すると通知を送って自身は停止します(実行中のサービスリストから消えます)
通知を送っているので、左上に通知のアイコンが出ています
Screenshot_20180828-115245.png

通知を確認するとサービスからの通知があります
Screenshot_20180828-115306.png

ドキュメント(docwiki)

4
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2