Delphi XE8のFiremonkey AndriodアプリケーションでGmailに添付されたファイルを開くには

AndroidのGmailアプリで添付ファイルを開いたときに、Firemonkeyアプリケーションで内容を表示する方法です。
今回はCSVファイルを開くアプリケーションを作成します。

Android 4.4.2とAndroid 5.1.1で動作を確認しました。
Inboxアプリでも動作することを確認しました。

最初に、CSVファイルのIntentを受け取ることができるように、AndroidManifest.template.xmlを編集します。
AndroidManifest.template.xmlはプロジェクトをビルドすると生成されます。

AndroidManifest.template.xmlをエディタで開き、次の行を追加します。
CSVファイルを対象としているため、mimeTypeは”text/csv”にしています。

        <intent-filter>  
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/csv" />
        </intent-filter> 

アプリケーションがアクティブになったときのイベントを取得できるようにします。

type
  TForm2 = class(TForm)
    procedure FormCreate(Sender: TObject);
    …
    function HandleAppEvent(AAppEvent: TApplicationEvent;
      AContext: TObject): Boolean;
  end;

procedure TForm2.FormCreate(Sender: TObject);
var
  AService: IFMXApplicationEventService;
begin
  if TPlatformServices.Current.SupportsPlatformService
    (IFMXApplicationEventService, IInterface(AService)) then
    AService.SetApplicationEventHandler(HandleAppEvent)
end;

function TForm2.HandleAppEvent(AAppEvent: TApplicationEvent;
  AContext: TObject): Boolean;
begin
  if AAppEvent = TApplicationEvent.BecameActive then
  begin
    //アプリケーションがアクティブになったときの処理
  end;
end;

Intentを受信する処理を記述します。

function TForm2.HandleAppEvent(AAppEvent: TApplicationEvent;
  AContext: TObject): Boolean;
var
  Intent: JIntent;
  AttachmentFileName: string;
  CSV: string;
begin
  if AAppEvent = TApplicationEvent.BecameActive then
  begin
    Intent := SharedActivity.getIntent;
    if Intent <> nil then
    begin
      if TJIntent.JavaClass.ACTION_VIEW.equals(Intent.getAction) then
      begin
        // 添付ファイルのファイル名
        AttachmentFileName := GetDisplayName(Intent.getData);
        // 添付ファイルのファイル名をMemo1に出力
        Memo1.Lines.Add('ファイル名=' + AttachmentFileName);

        // 添付ファイルの内容
        if StringToJString('content').equals(Intent.getScheme) then
        begin
          // 添付のCSVファイルのデータ
          CSV := GetContent(Intent);
          // 添付ファイルの内容をMemo1に出力
          Memo1.Lines.Add('添付のCSVファイルのデータ');
          Memo1.Lines.Add(CSV);
        end;

      end;
    end;
  end;
  Result := True;
end;

添付ファイルのファイル名を取得する関数です。

/// <summary>
/// 添付ファイルのファイル名を取得する
/// </summary>
function GetDisplayName(Uri: Jnet_Uri): string;
var
  Cursor: JCursor;
  ColumnIndex: Integer;
begin
  if Uri = nil then
    Exit;

  Cursor := SharedActivity.getContentResolver.query(Uri, nil, nil, nil, nil);
  Cursor.moveToFirst;
  ColumnIndex := Cursor.getColumnIndex
    (TJMediaStore_MediaColumns.JavaClass.DISPLAY_NAME);
  if ColumnIndex >= 0 then
  begin
    // 添付ファイルのファイル名
    Result := JStringToString(Cursor.GetString(ColumnIndex));
  end;
  Cursor.close;
end;

添付のCSVファイルのデータを取得する関数です。

/// <summary>
/// 添付のCSVファイルのデータを取得する
/// </summary>
function GetContent(Intent: JIntent): string;
var
  InputStream: JInputStream;
  Buffer: TArray<System.Byte>;
begin
  InputStream := SharedActivity.getContentResolver.openInputStream
    (Intent.getData);
  Buffer := JInputStreamToByteArray(InputStream);
  // 文字コードはUTF-8決め打ち
  Result := TEncoding.UTF8.GetString(Buffer);
end;

InputStreamのデータを取得してバイト配列を返す関数です。

/// <summary>
/// InputStreamのデータを取得してバイト配列を返す
/// </summary>
function JInputStreamToByteArray(InputStream: JInputStream)
  : TArray<System.Byte>;
var
  List: TList<System.Byte>;
  I: Integer;
begin
  List := TList<System.Byte>.Create;
  try
    while True do
    begin
      I := InputStream.read;
      if I < 0 then
        Exit(List.ToArray);
      List.Add(System.Byte(I));
    end;
  finally
    List.Free;
  end;
end;

以上で完成です。

Gmailアプリで、CSVファイルを開きます。

intent-1

Firemonkeyアプリケーションが起動し、添付ファイルのファイル名と内容が表示されました。

intent-2

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です