Android サービスの作成

提供: RAD Studio
移動先: 案内検索

Android アプリケーションの作成 への移動

Android サービスとは、ユーザー インターフェイスを持たない、バックグラウンド タスクを実行するアプリケーションです。このサービスには、本質的に以下の 2 種類があります。

  • 起動型サービス: このサービスは Android アプリケーションによって起動されます。サービスは、アプリケーションが終了した後も、バックグラウンドで無期限に動作し続けることができます。この種類のサービスは、通常、1 つのタスクを実行し、それが終了すると自動的に停止します。
  • バインド型サービス: このサービスは、Android アプリケーションにバインドされている間のみ動作します。アプリケーションとサービスの間で対話が行われ、アプリケーションがバインドを解除するまでアクティブなままになります。複数のアプリケーションを同じ 1 つのサービスにバインドすることができます。

Android サービス プロジェクトを作成するには:

  1. Android サービスの新規作成 ウィザードを使用すると、Android サービスを作成することができます。「Android サービスの作成」を参照してください。
  2. Use the 新規 Android サービスの追加 ウィザードを使用すると、Android サービスマルチデバイス アプリケーションに追加することができます。「アプリケーションへの Android サービスの追加」を参照してください。

スタンドアロン アプリケーションと Android サービス プロジェクト アプリケーションには、異なる点があります。

Android サービスの作成

RAD Studio では、Android サービス プロジェクトを作成するための、ウィザードが用意されています。

Android サービス プロジェクトを新規作成するには、[ファイル|新規作成|その他...]を選択し、それから以下を選択します。

  • [Delphi プロジェクト|Android サービス]

このウィザードで、サービスの種類(ローカルまたはリモート)を指定します。

  • ローカル サービスは、そのアプリケーションだけで使用できる private のサービスです。Android マニフェスト ファイルに以下の行が追加され、他のアプリケーションからのアクセスが阻止されます。
<service android:exported="false" android:name="com.embarcadero.services.<service_name>"/>
  • リモート サービスは public であり、他のアプリケーションからアクセスすることができます。Android マニフェスト ファイルに以下の行が追加され、サービスへのアクセスが認められます。
<service android:exported="true" android:name="com.embarcadero.services.<service_name>"/>

さまざまなオプションの詳細は、「Android サービス」を参照してください。

Android マニフェスト属性の詳細は、「Exported Provider Element(provider 要素のエクスポート)」を参照してください。

メモ: 開発者が <SERVICE-NAME>.template.java ファイル(ローカル テンプレート ファイル)を変更しており、Android Service フォルダのルート フォルダからの JavaClasses フォルダが前の製品リリースで生成されている場合、同様の変更を、RAD Studio 10.4 で生成されたローカル テンプレート ファイルにも行うことが大変重要です。

アプリケーションへの Android サービスの追加

Android サービスはスタンドアロン アプリケーションではありませんが、マルチデバイス アプリケーションと一緒に動作します。

作成したサービスは、プロジェクト ウィンドウに lib<プロジェクト名>.so という名前で表示されます。

Android サービス プロジェクトをマルチデバイス アプリケーションに追加するには:

  1. ビジュアル コンポーネントをデータ モジュールに、関数と手続きをコードに追加します。
  2. Android サービス プロジェクトを保存します。
    メモ 1: Android サービス プロジェクトは、それぞれ異なるフォルダに保存してください。
    メモ 2: Android サービス プロジェクトに Service という名前を付けてはなりません。
  3. Android サービス プロジェクトをビルドしてからアプリケーションに追加し、バイナリ ファイルを生成します。
  4. サービスを追加する先のアプリケーションをプロジェクト ウィンドウに追加します。
    1. 既存のアプリケーションの場合には、プロジェクト グループを右クリックし、[既存プロジェクトを追加...]を選択します。
    2. マルチデバイス アプリケーションを新規作成する場合は、プロジェクト グループを右クリックし、[新規プロジェクトを追加...]を選択してから、以下を選択します。
      • [Delphi プロジェクト|マルチデバイス アプリケーション]
  5. そのマルチデバイス アプリケーションで、ターゲット プラットフォームに[Android]を選択します。
    1. [Android]ターゲット プラットフォームを右クリックし、[Android サービスの追加...]を選択します。
    2. [新規 Android サービスの追加]ウィザードが開きます。 新しい Android サービスを追加する際、2 つのオプションがあります。次のいずれかを選択します。
      1. [プロジェクトの基底パスから自動的にファイルを検索する]
        • このオプションを選択すると、Android Service プロジェクトが保存されるフォルダを選択することができます。ウィザードは、必要なファイル群を自動的に検索します。
          警告: 指定されたフォルダに Andoird サービスが複数あった場合、ウィザードはそれらからランダムに 1 つ選択します。特定の Android サービスを追加したい場合は、2 番目のオプションを利用します。
        • Next をクリックします。
        • ProjectOptionsEllipsis.jpg をクリックして、Android サービス プロジェクトを保存するフォルダを選択します。
      2. [必要なファイルをすべて手動で選択する]
        • このオプションを選択すると、必要なファイルはすべて手動で選択することができます。
          警告: ステップ 3 が完了していることを確認してください。そうでなければ、バイナリ ファイルが利用可能になりません。
        • Next をクリックします。
        • ProjectOptionsEllipsis.jpg をクリックして、要求するファイルをそれぞれ選択します。
    3. [次へ]をクリックします。
      1. 何も問題なければ、マルチデバイス アプリケーションに追加されるファイルがリストに表示されます。
      2. Android サービスのパスの情報を要求するウィンドウが開いた場合には、Android サービスを保存しビルドしてからやり直してください。
  6. [完了]をクリックすると、以下のファイルがアプリケーションに追加されます。
    • メインのバイナリ ファイル、lib<プロジェクト名>.so。 バイナリ ファイルは配置マネージャに追加されます。
    • libProxyAndroidService.so ファイル。このライブラリは配置マネージャに追加されます。
      メモ: このファイルは、アプリケーションに追加されたすべてのサービスで共有されます。
    • Java アーカイブ ファイル <プロジェクト名>.jar。 この jar ファイルは、プロジェクト ウィンドウ[ライブラリ]ノード([Android]ターゲット プラットフォームの下にある)に追加されます。
    • データ モジュール ファイルの <プロジェクト名>.pas ファイル。データ モジュールはプロジェクト ウィンドウに追加されます。
  7. マルチデバイス アプリケーションをコンパイルして、Android マニフェスト ファイルを生成します。先ほど選択したサービスのタイプ(ローカルまたはリモートで)に応じた行が自動的に追加されます。「Android サービスの作成」を参照してください。
    メモ: サービスごとに、対応する <service> の宣言を AndroidManifest.xml に追加する必要があります。これは IDE によって自動的に追加されます。

アプリケーションへの複数の Android サービスの追加

任意の数のサービスを Android アプリケーションに追加することができます。

追加するサービスそれぞれについて、「アプリケーションへの Android サービスの追加」の手順を実施してください。

以下はその際の注意事項です。

  • Android Services プロジェクトが複数、同じフォルダ内にあり、そこから特定の 1 つを含みたい場合、ステップ 5.2 での 2 つ目のオプションを選択してください。そうでなければ、ウィザードは希望していない Android サービスを追加する可能性があります。
  • プロジェクトそれぞれに異なる名前を付けてから、メイン アプリケーションに追加します。
    • Android サービス プロジェクト:lib<サービス名>.so。
    メモ: Android サービス プロジェクトに Service という名前を付けてはなりません。

プロジェクトの依存関係

マルチデバイス アプリケーションに追加された Android サービス プロジェクトは、プロジェクト間の依存関係 として表示されます。

ホスト アプリケーションに関連づけられた Android サービス プロジェクトは、[プロジェクト間の依存関係] で自動的に有効になり、ホスト アプリケーションの前に常にビルドされます。

アプリケーションからの Android サービスの削除

そのマルチデバイス アプリケーションで、ターゲット プラットフォームに[Android]を選択します。

  1. [Android]ターゲット プラットフォームを右クリックし、[Android サービスの削除...]を選択します。
  2. Android サービスの削除 ウィザードが現れます。
  3. 一覧から削除するサービスを選択します。
  4. Next をクリックします。
  5. ウィザードでは、データ モジュール、.so 拡張子ファイル、.jar 拡張子ファイルの削除など、実行するアクションのリストが表示されます。
  6. Finish をクリックします。

サービスの起動

サービスは、ALocalServiceConnection.StartService('<サービス名>')ALocalServiceConnection.BindService('<サービス名>')、または ARemoteServiceConnection.StartService('<サービス名>')ARemoteServiceConnection.BindService('<サービス名>') を使って起動することができます。

起動時またはバインド時に、TLocalServiceConnection 変数を具体的なサービスに初期化します。その後、残りのメソッドでサービス名を参照する必要はありません。

Android サービスをマルチデバイス アプリケーションに追加したら、以下を行います。

  1. 以下のユニットをインターフェイスの uses 句 に追加します。
    Uses
      System.Android.Service; // Unit that contains the methods to work with services.
    
  2. <サービス名>.pas ユニットを実装の uses 句に追加します。これで、サービス データ モジュールに定義されたすべてのメソッドを使用できるようになります。
    implementation
    
    uses
      MyLocalService; //Key sensitive
    
    {$R *.fmx}
    
  3. ローカル サービスの場合は TLocalServiceConnetion 変数、リモート サービスの場合は TRemoteServiceConnection 変数を作成します。
    1. TLocalServiceConnection/TRemoteServiceConnection 変数を宣言します。
      type
        TForm1 = class(TForm)
          ...
        private
          { Private declarations }
          FServiceConnection1: TLocalServiceConnection; // For a local service.
          FServiceConnection2: TRemoteServiceConnection; // For a remote service.
        public
          { Public declarations }
        end;
      
    2. TLocalServiceConnection/TRemoteServiceConnection 変数を作成します。
      FServiceConnection1 := TLocalServiceConnection.Create; // For a local service.
      FServiceConnection2 := TRemoteServiceConnection.Create; // For a remote service.
      

起動型サービス

起動型サービスの場合は、StartService('<サービス名>') を呼び出してサービスを起動します。

サービスを起動型として使用する場合、自分でサービス プロセスを管理し、JavaService.stopSelf; を使ってサービスを停止する必要があります。

スティッキーでの起動

サービスの OnStartCommand イベントは、デフォルトでは START_NOT_STICKY と定義されています。

  • START_STICKY は、明示的に起動され、必要に応じて停止されるサービスに使用します。システムは、サービスが強制終了されると、サービスの再起動を試みます。
  • START_NOT_STICKY は、送られてきたコマンドを処理する間だけ実行しておきたいサービスに使用します。プロセスが強制終了されても、サービスは自動的に再起動されません。

OnStartCommand イベントを START_STICKY にしたい場合は、それをサービスに指定する必要があります。

function TService1DM.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
  Result := TJService.JavaClass.START_STICKY;
end;

詳細は、「Service Lifecycle(サービスのライフサイクル)」を参照してください。

バインド型サービス

バインド型サービスの場合は、BindService('<サービス名>') を呼び出してサービスをバインドし、対話を始められるようにしたり、UnBindService を呼び出してサービスとの接続を解除します。

詳細は、「Bound Services(バインド型サービス)」を参照してください。

BindService/UnBindService メソッド

メイン アプリケーションで BindService('<サービス名>') を呼び出すと、サービスが動作しているメモリ アドレスを指すポインタが接続変数に設定されます。

特定のサービスに対する接続を確立した後で、UnBindService を呼び出したときに、そのサービスにバインドしているのがそのアプリケーションだけであれば、サービスは自身を解放します。 メイン アプリケーションの接続変数は、同じメモリ アドレスを指したままになることに注意してください。 同じサービスに再びバインドするとメイン アプリケーションがクラッシュする可能性があります。サービスのメモリ アドレスが不正である可能性があるためです。

この状況に対処する方法は 2 つあります。

  • [UnSafe] 属性を使用して ARC を使用しないようにする。
  • サービスとのバインドを解除する前に変数に Nil を代入する

[Unsafe] 属性の利用

  private
    { Private declarations }
    [Unsafe] Service1: TAndroidService1DM;

OnBind イベント

アプリケーションの BindService('<サービス名>') を呼び出すと、Android サービス プロジェクトで OnBind イベントが発生します。OnBind メソッドは、サービスとの接続を実際に管理する責任を負う IBinder オブジェクトを返します。

OnBind メソッドを上書きすると、メイン アプリケーションがサービスからデータ モジュールを取り出すために必要な IBinder オブジェクトが、イベントから返されなくなります。

OnBind メソッドを使用するには:

  • OnBind メソッドで IBinder オブジェクトを返します。
function TAndroidServiceDM.AndroidServiceBind(const Sender: TObject;
  const AnIntent: JIntent): JIBinder;
begin
  // .... User's code
  Result := GetBinder(Self);
end;

関連項目