2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

Android の StartService のアプリを Delphi で作ってみた」を書いたので、もうひとつの BindService も書かないと

BindService は StartService と同様にアプリによって開始されます
BindService でサービスに接続して、UnBindService でサービスとの接続を解除します
StartService が自身で停止するのと違い、BindService の場合は、他から使われている限り実行し続け、誰からも使われなくなったら、サービスを破棄します
参考: Android Developer - Service

どんなアプリを作るの?

Android の StartService のアプリを Delphi で作ってみた で作ったアプリ・サービスを修正・拡張します
修正・拡張するので、メインのアプリにサービスを登録する作業を再度行なう必要はありません
修正・拡張の内容ですが

  • メイン側のアプリは BindService のボタンを押すとサービスを開始し、BindService でそのサービスに接続します
  • メイン側のアプリは UnBindService のボタンを押すと、サービスとの接続を解除します
  • サービス側は、BindService の機能を追加しますが、やることは同じで通知を行ないます
  • サービス側では解除=サービス停止とします

メイン側の画面の拡張

ボタンを1個、新しく配置するだけの簡単なお仕事
分かりやすいように、「BindService」「UnBindService」と Text プロパティを変更
BindService01.png

メイン側の動作の拡張

「BindService」のボタンのクリックイベントを次のように修正します

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Service 起動
  if mService = nil then begin
    mService := TLocalServiceConnection.Create;
    mService.StartService('Project2');
  end;

  // Service に Bind
  mService.BindService('Project2', 0);
end;

「UnBindService」のボタンのクリックイベントを次のように記述します

procedure TForm1.Button2Click(Sender: TObject);
begin
  if mService <> nil then begin
    mService.UnbindService;  // Service との接続解除
    mService := nil;
  end;
end;

サービス側の拡張

DM(TDM) に新たに OnBind イベントと、OnUnBind イベントを追加
BindService02.png

OnStartCommand イベントのコードを次のように修正します

function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
  // サービスの開始
  // StartService は result を返す
  Result := TJService.JavaClass.START_STICKY;
end;

OnBind イベントのコードを次のように記述します

function TDM.AndroidServiceBind(const Sender: TObject; const AnIntent: JIntent): JIBinder;
var
  mNotice: TNotification;
begin

  // BindService として通知の実行
  mNotice := NotificationCenter1.CreateNotification;
  mNotice.Title := 'BindService通知';
  mNotice.AlertBody := 'メッシャアーッ';
  NotificationCenter1.PresentNotification(mNotice);
  mNotice.DisposeOf;

  // IBinder オブジェクトを戻り値として返す
  Result := GetBinder;
end;

OnUnBind イベントのコードを次のように記述します

function TDM.AndroidServiceUnBind(const Sender: TObject; const AnIntent: JIntent): Boolean;
begin
// このサンプルでは解除=停止
// サービスの停止
  JavaService.stopService(AnIntent);
  Result := False;
end;

動かしてみる

まずはアプリ起動(この画面を撮っていなかったのに後から気付いたため、この画面ショットだけ時系列がズレていますw)
Screenshot_20180904-112723.png

BindService をタップするとサービスが起動し、そのサービスに接続して「通知」が行なわれます
Screenshot_20180904-111717.png

通知内容
Screenshot_20180904-111725.png

UnBindService をタップするとサービスとの接続を解除して、サービスを停止します
Screenshot_20180904-111804.png

BindService のボタンを続けて2回タップしても通知は1つだけです
これは、まだ Bind が解除されていないので OnBind イベントが発生しないのです
UnBindService のボタンをタップしてから、BindService のボタンをタップすると、OnBind イベントが発生し通知が行なわれます

参考

BindService のライフサイクル
Android Developer より

alt

あとがき

Delphi で Android サービスを作る際に 4 つの選択

  • ローカルサービス
  • インテントローカルサービス
  • リモートサービス
  • インテントリモートサービス

が出てきます

「ローカル」と「リモート」の違いは、
ローカル - そのアプリだけで使用できる private のサービス
リモート - public であり、他のアプリからアクセスすることができる
です

「インテントxxxxサービス」は、サービスで IntentService を使用したい場合に選択します
IntentService はバッググラウンドで特定のタスクを実行し、ワーカスレッドでタスクキューを受け取り順に処理します
サービスの停止はキュー内の作業が全て終わったときに自動的に行なわれるので、明示的に停止する必要はありません

2
1
0

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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?