トップへ(mam-mam.net/)

Androidのフォトライブラリを起動し選択写真を表示 ~Delphiソースコード集

検索:

Androidのフォトライブラリを起動し選択写真を表示 ~Delphiソースコード集

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

ファイル⇒新規作成⇒マルチデバイス アプリケーション -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);
          BitmapSurface.Free;
        end;
      end;
    end;
  end;
end;

end.