Delphiでお手軽プログラミング

Delphiでお手軽プログラミングメニュー

Androidのフォトライブラリ(フォト、ギャラリー)アクテビティを起動して選択した写真を表示する

フォトライブラリから選択写真を受け渡して表示するアプリを作成する

~IntentをstartActivityForResultで起動する場合


プロジェクトの作成とファイルの保存

ファイル⇒新規作成⇒マルチデバイス アプリケーション -Delphi をクリックします。
「空のアプリケーション」を選択してOKを押します。

「すべて保存」ボタンを押して、プロジェクト(PhotoLibrary.dproj等)とユニット(Unit1.pas等)に名前を付けて保存します。

ターゲット設定、画面設計

(PCに実機をUSBで接続して)右上ペインのターゲットプラットフォームを展開して「Android64ビット」(接続した実機)をダブルクリックして切り替えます。
右下ペインのパレットからTPanelをドラッグし、プロパティ「Align」を[Top]に設定します。
右下ペインのパレットからTImageをドラッグし、プロパティ「Align」を[Client]に設定します。
  MultiResBitmapプロパティに白紙の画像ファイルを設定します。(2×2ドットのjpgファイルなどを事前に作成してあてがいます。)
右下ペインのパレットからTButtonをPanel1の上にドラッグします。



ソースコードの記述

startActivityForResultでフォトライブラリから選択された画像をもらう場合はExternal権限等が必要ありません。
以下ソースコードを追加します。
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.StdCtrls,
  FMX.Objects,FMX.Controls.Presentation,
  Androidapi.Helpers,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI.GraphicsContentViewText,
  System.Messaging,        //TMessageManager TMessage
  Androidapi.JNI.App,   //TJActivity startActivityForResult
  FMX.Surfaces,         //TBitmapSurface
  FMX.Helpers.Android  //JBitmapToSurface
  ;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Image1: TImage;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private 宣言 }
  public
    { public 宣言 }
    //「フォト」アプリを開いて写真が選択された後に
    //メッセージをもらう時に使用するID
    MessageSubscriptionID: Integer;
    //「フォト」アプリを開いて写真を選択した後に
    //メッセージをもらう関数
    procedure HandleActivityMessage(const Sender: TObject; const M: TMessage);
  end;

var
  Form1: TForm1;

const
  //「フォト」アプリを開く時に渡して「フォト」で写真が選択された
  //メッセージをもらう時にこの値が返ってくる
  REQUEST_CODE_VALUE:Integer=2345;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
  Intent: JIntent;
begin
  //メッセージハンドラを登録
  MessageSubscriptionID :=
    TMessageManager.DefaultManager.SubscribeToMessage(
      TMessageResultNotification, HandleActivityMessage);

  //Intent := TJIntent.Create;
  Intent:=TJIntent.JavaClass.init;
  Intent.setType(StringToJString('image/*'));

  //以下の場合だと、android標準の「フォト」アプリ指定
    Intent.setAction(TJIntent.JavaClass.ACTION_GET_CONTENT);
    Intent.setPackage(StringToJString('com.google.android.apps.photos'));

  //以下の場合は、写真を扱うアプリから選択する
    //Intent.setAction(TJIntent.JavaClass.ACTION_PICK);

  //REQUEST_CODE_VALUEでリクエストコードを送る
  TAndroidHelper.Activity.startActivityForResult(
    Intent, REQUEST_CODE_VALUE);
end;

procedure TForm1.HandleActivityMessage(const Sender: TObject;
  const M: TMessage);
var
  RequestCode, ResultCode: Integer;
  Data: JIntent;
  InputStream: JInputStream;
  JavaBitmap: JBitmap;
  BitmapSurface:TBitmapSurface;
begin
  if M is TMessageResultNotification then
  begin
    RequestCode:=TMessageResultNotification(M).RequestCode;
    ResultCode:=TMessageResultNotification(M).ResultCode;
    Data:=TMessageResultNotification(M).Value;

    //メッセージハンドラの解除
    TMessageManager.DefaultManager.Unsubscribe(
      TMessageResultNotification, MessageSubscriptionID);

    //渡したリクエストコードと/戻り値のリクエストコードが一致する場合
    if RequestCode=REQUEST_CODE_VALUE then
    begin
      if ResultCode=TJActivity.JavaClass.RESULT_OK then
      begin
        if Assigned(Data) then
        begin
          InputStream :=
            TAndroidHelper.Activity.getContentResolver.openInputStream
            (Data.getData);
          //Java形式のBitmapに変換
          JavaBitmap := TJBitmapFactory.JavaClass.decodeStream(InputStream);
          //Java形式のBitmapからBitmapSurfaceへ変換
          BitmapSurface := TBitmapSurface.Create;
          JBitmapToSurface(JavaBitmap, BitmapSurface);
          Image1.Bitmap.Assign(BitmapSurface);
        end;
      end;
    end;
  end;
end;

end.




Copyright 2019 Mam