Androidのフォトライブラリ(フォト、ギャラリー)アクテビティを起動して選択した写真を表示する ~Delphiでお手軽プログラミング
TActionListのTTakePhotoFromLibraryActionを使用してAndroidのフォトライブラリ(フォト、ギャラリー)から選択した写真をアプリで表示する方法です。
- (参考)
-
TTakePhotoFromLibraryActionは選択した写真を外部ストレージに保存してから取り出しているようです。
この為、Android6.0(API Level23)以降で使う場合には、外部ストレージへのアクセス権限が必要になり、権限取得などが面倒になります。
よって、「startActivityForResultでフォトライブラリを起動して選択した写真を表示する」をお勧めします。
プロジェクトの作成とファイルの保存
ファイル⇒新規作成⇒マルチデバイス アプリケーション -Delphi をクリックします。「空のアプリケーション」を選択してOKを押します。
ターゲット設定、画面設計
(PCに実機をUSBで接続して)右上ペインのターゲットプラットフォームを展開して「Android64ビット」(接続した実機)をダブルクリックして切り替えます。右下ペインのパレットからTPanelをドラッグし、プロパティ「Align」を[Top]に設定します。
右下ペインのパレットからTImageをドラッグし、プロパティ「Align」を[Client]に設定します。
MultiResBitmapプロパティに白紙の画像ファイルを設定します。(2×2ドットのjpgファイルなどを事前に作成してあてがいます。)
右下ペインのパレットからTButtonをPanel1の上にドラッグします。
右下ペインのパレットからTActionListをドラッグします。
アクションの設定、ソースコードの記述
ActionList1をダブルクリックします。左上のボタンから「標準のアクションの新規作成」をクリックします。TTakePhotoFromLibraryAction1を選択(クリック)します。
親ウィンドウにある左下ペイン「オブジェクトインスペクタ」の「イベント」タブを選択し、 [OnDidFinishTaking]の右の空欄をダブルクリックします。
OnDidFinishTakingのプロトタイプ宣言等が自動で記述されたソースコードエディタに切り替わりますので、以下ソースを入力します。
procedure TForm1.TakePhotoFromLibraryAction1DidFinishTaking(Image: TBitmap);
begin
Image1.Bitmap.Assign(Image);
end;
キーボードから「F12」キーを押してデザインに切り替えます。Button1をダブルクリックします。
OnClickのプロトタイプ宣言等が自動で記述されたソースコードエディタに切り替わりますので、以下ソースを入力します。
procedure TForm1.Button1Click(Sender: TObject);
begin
TakePhotoFromLibraryAction1.ExecuteTarget(nil);
end;
「プロジェクト」⇒「オプション」をクリックします。
「アプリケーション」⇒「使用する権限」から[外部ストレージの読み取り][外部ストレージへの書き込み]にチェックを入れます。
保存ボタンをクリックします。
Android6(APIレベル23)以降の対応
Android6(APIレベル23)より前なら以上で動くのですが、APIレベル23以降は外部ストレージへのアクセス権限をプログラムで制御する必要がある。キーボードの「F12」キーを押してデザインモードに切り替え、左上ペイン「構造」の[Form1]をクリックします。
左下ペインの「オブジェクトインスペクタ」の「イベント」タブを選択し、[OnCreate]の右側空欄をダブルクリックします。
以下ソースコードを追加します。
procedure TForm1.FormCreate(Sender: TObject);
begin
RequestPermissions;
end;
更にたくさん以下赤字部分のソースコードを記述します。(赤字はすべてAPIレベル23以降対応ソースコードです)
unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Actions, FMX.ActnList, FMX.StdActns, FMX.MediaLibrary.Actions, FMX.Objects, FMX.StdCtrls, FMX.Controls.Presentation,System.Permissions; type TForm1 = class(TForm) Panel1: TPanel; Button1: TButton; Image1: TImage; ActionList1: TActionList; TakePhotoFromLibraryAction1: TTakePhotoFromLibraryAction; procedure TakePhotoFromLibraryAction1DidFinishTaking(Image: TBitmap); procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { private 宣言 } public { public 宣言 } procedure PermissionRequestResult( Sender: TObject; const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>); procedure RequestPermissions(); end; var Form1: TForm1; implementation {$R *.fmx} uses Androidapi.Helpers, Androidapi.JNI.Os, Androidapi.Jni.Support, FMX.DialogService; procedure TForm1.Button1Click(Sender: TObject); begin TakePhotoFromLibraryAction1.ExecuteTarget(nil); end; procedure TForm1.FormCreate(Sender: TObject); begin RequestPermissions; end; procedure TForm1.PermissionRequestResult(Sender: TObject; const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>); begin //外部ストレージの権限があるか if (AGrantResults[0]<>TPermissionStatus.Granted) then begin //権限がない場合 //「□今後は表示しない」チェックボックスにチェックが入っているか if (TJActivityCompat.JavaClass.shouldShowRequestPermissionRationale( TAndroidHelper.Activity, TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE)) then begin //「□今後は表示しない」チェックボックスにチェックが入っていない場合 // 非同期でダイアログを表示して説明と許可を要求 TDialogService.MessageDialog( '許可しないとアプリが動作しません。',TMsgDlgType.mtInformation, [TMsgDlgBtn.mbOK],TMsgDlgBtn.mbOk,0, procedure (const AResult: TModalResult) begin //2回目以降は「□今後は表示しない」チェックボックスが表示される RequestPermissions(); end); end else begin //「□今後は表示しない」チェックボックスにチェックが入っている TDialogService.MessageDialog( '権限が無いため終了します。「設定⇒アプリと通知」から権限設定してください。', TMsgDlgType.mtError,[TMsgDlgBtn.mbOK],TMsgDlgBtn.mbOK,0, procedure(const AResult:TModalResult) begin Application.Terminate; end ); end; end; end; procedure TForm1.RequestPermissions; var //外部ストレージの書き込み権限があると読み込み権限も発生する //FPmsReadExternalStorage:string; FPmsWriteExternalStorage:string; begin FPmsWriteExternalStorage := JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE); PermissionsService.RequestPermissions( [FPmsWriteExternalStorage],PermissionRequestResult); end; procedure TForm1.TakePhotoFromLibraryAction1DidFinishTaking(Image: TBitmap); begin Image1.Bitmap.Assign(Image); end; end.