Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
FMX video'nun dosya yolunu çekme
#1
Merhabalar. Mobil cihazda galeriden video seçip bu videoyu uygulamamda oynatmak istiyorum. TakePhotoFromLibraryAction gibi action olmadığı için java class'ları yazılması gerekiyor. Dosya seçme işlemi yapıyorum, fakat dosyanın yolunu çekemiyorum. Yardımcı olur musunuz?

unit Unit2;

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.Controls.Presentation,

 System.Permissions,
 System.Messaging,

 Androidapi.JNI.Net,
 Androidapi.JNI.GraphicsContentViewText,
 Androidapi.JNI.JavaTypes,
 Androidapi.Helpers,
 Androidapi.JNI.App,
 FMX.Platform.Android,
 Androidapi.JNIBridge,

 FMX.StdActns,
 FMX.MediaLibrary.Actions, FMX.Media;

type
 TForm2 = class(TForm)
   Label1: TLabel;
   Button1: TButton;
   MediaPlayerControl1: TMediaPlayerControl;
   MediaPlayer1: TMediaPlayer;
   Timer1: TTimer;
   procedure Button1Click(Sender: TObject);
   procedure Timer1Timer(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
   // Handling Result :
   procedure HandleActivityMessage(const Sender: TObject; const M: TMessage);
   function OnActivityResult(RequestCode, ResultCode: Integer;
     Data: JIntent): Boolean;
   function HandleIntentAction(const Data: JIntent): Boolean;
 end;

var
 Form2: TForm2;
 fVideoFilename: string;
 FMessageSubscriptionID: integer;

implementation

{$R *.fmx}

procedure TForm2.Button1Click(Sender: TObject);

var
 chooserIntent, Intent: JIntent;
 ResultInt: integer;
begin

 FMessageSubscriptionID := TMessageManager.DefaultManager.SubscribeToMessage
   (TMessageResultNotification, HandleActivityMessage);

 intent := TJIntent.Create;
 intent.setType(StringToJString('video/*'));
 intent.setAction(TJIntent.JavaClass.ACTION_GET_CONTENT);

 chooserIntent := TJIntent.JavaClass.createChooser(intent,
   StrToJCharSequence('Choose media file'));
 TAndroidHelper.Activity.startActivityForResult(chooserIntent,
   FMessageSubscriptionID);
 // SharedActivity.startActivityForResult(intent, 0);
 // SharedActivity.startActivityForResult(chooserIntent, 0);
 { var
   Intent: JIntent;
   begin
   FMessageSubscriptionID :=
   TMessageManager.DefaultManager.SubscribeToMessage
   (TMessageResultNotification, HandleActivityMessage);

   Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_GET_CONTENT);
   Intent.setType(StringToJString('video/*'));
   Intent.setAction(TJIntent.JavaClass.ACTION_GET_CONTENT);
   //Intent.putExtra(TJIntent.JavaClass.EXTRA_ALLOW_MULTIPLE, true);
   SharedActivity.startActivityForResult(Intent, 0);
 }
end;

procedure TForm2.HandleActivityMessage(const Sender: TObject;
 const M: TMessage);
begin
 // if M is TMessageResultNotification then
 // OnActivityResult(TMessageResultNotification(M).RequestCode,
 // TMessageResultNotification(M).ResultCode,
 // TMessageResultNotification(M).Value);

 if M is TMessageResultNotification then
   if HandleIntentAction(TMessageReceivedNotification(M).Value) then
   begin
     // A valid filename has been returned
     // Do The Videofile processing
   end;
 Label1.text := fVideoFilename;

 Timer1.Enabled := true;
end;

function TForm2.HandleIntentAction(const Data: JIntent): Boolean;
var
 P: TJavaObjectArray<Jstring>;
 // in case you want only specific fields... not used here. I have passed nil to get all the columns.
 C: JCursor;
 I: integer;
begin
 P := nil;
 // The following makes no difference
 // P:=TJavaObjectArray<Jstring>.create(1);
 // P.Items[0]:=StringToJstring('_data');

 // this is suppose to give the information back to C ( : JCursor)
 C := TAndroidHelper.Activity.getContentResolver.query(Data.getData, nil,
   // when projection is nil... it returns all columns. Ideally, you should only ask for the columns you need
   StringToJString(''),
   // java accepts nil... but you cannot give nil here, you need to give an empty JString
   nil, StringToJString(''));
 // java accepts nil... but you cannot give nil here, you need to give an empty JString

 C.moveToFirst;
 Result := false;
 for I := 0 to C.getColumnCount - 1 do
 begin
   if JStringToString(C.getColumnName(I)) = '_data' then
   // '_data' column contains the path... you can use this to create the filestream to upload or do whatever....
   begin
     // fVideoFilename is a field of the form
     fVideoFilename := JStringToString(C.getString(I));
     Result := true;
     Break;
   end;
 end;
 if not Result then
   fVideoFilename := 'video file boş';
 // P.Free;
end;

function TForm2.OnActivityResult(RequestCode, ResultCode: Integer;
 Data: JIntent): Boolean;
var
 filename: string;
begin
 Result := false;
 TMessageManager.DefaultManager.Unsubscribe(TMessageResultNotification,
   FMessageSubscriptionID);
 FMessageSubscriptionID := 0;

 Label1.text := ResultCode.ToString;
 Label1.text := Label1.text + slinebreak + RequestCode.ToString;

 if Assigned(Data) then
 begin
   //
   filename := JStringToString(Data.getStringExtra(StringToJString('RESULT')));
   filename := JStringToString
     (Data.getStringExtra(TJIntent.JavaClass.EXTRA_TEXT));
   ShowMessage('Result : ' + filename);
   Label1.text := Label1.text + slinebreak + filename;
   Label1.text := Label1.text + slinebreak + ' true';
 end
 else
 begin
   Label1.text := Label1.text + slinebreak + ' false';

 end;

 if RequestCode = TJActivity.JavaClass.RESULT_OK then
 begin

   if Assigned(Data) then
   begin
     //
     filename := JStringToString
       (Data.getStringExtra(StringToJString('RESULT')));
     filename := JStringToString
       (Data.getStringExtra(TJIntent.JavaClass.EXTRA_TEXT));
     ShowMessage('Result : ' + filename);
     Label1.text := Label1.text + slinebreak + filename;
     // memo1.Lines.Add(filename);
   end;

 end
 else if ResultCode = TJActivity.JavaClass.RESULT_CANCELED then
 begin
   ShowMessage('No');
 end;
 Result := true;

end;

procedure TForm2.Timer1Timer(Sender: TObject);
begin
 Timer1.Enabled := false;

 if FileExists(fVideoFilename) then
 begin
   MediaPlayer1.filename := fVideoFilename;
   MediaPlayer1.Play;

 end
 else
 begin
   ShowMessage('Dosya bulunamadı: ' + fVideoFilename);
 end;

end;

end.


Ek Dosyalar
.zip   VideoSelect.zip (Dosya Boyutu: 13,39 KB / İndirme Sayısı: 4)
Cevapla
#2
@skaracan,
TakePhotoFromLibraryAction ın olmadığına emin misimniz? ---> TakePhotoFromLibraryAction
Begin : = end / 2;
Cevapla
#3
@skaracan

ACTION_GET_CONTENT kullanmak yerine ACTION_OPEN_DOCUMENT ile erişim yaparsanız External / Internal hafıza alanı olarak "en azından kullanıcının seçmesini sağlayarak" konum erişimi imkanınız olur.

Gelen içerik (GetAuthority ile sorguladığınız içerikten kasıt) eğer "com.android.providers.media.documents" gibi bir kaynaktan geliyorsa bunun kaynağına fiziki olarak erişebiliyorsunuz ve dosyayı fiziki olarak alabiliyorsunuz anlamındadır. Ancak URI içeriğinden AbsolutePath üretme imkanı olamıyor. En azından geçmiş tecrübelerimle ben öyle biliyorum. Bu kaynak kullanıcının mobil cihazı olabildiği gibi "OneDrive vb" cloud alanları da olabiliyor. Dahili ve harici kaynakları bu statüyle geliyorsa şekilde CLOUD okuma gibi değerlendirileceğinden path de ona göre URI olarak adresleniyor.
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla
#4
TakePhotoFromLibraryAction XE7'den beri kullanıyorum ben.
Cevapla
#5
İlginiz için teşekkür ederim. TakePhotoFromLibraryAction sadece galeriden fotoğraf seçmek için. Benim isteğim galeriden video seçmekti. Aşağıdaki kodlar işimi gördü. Ayrıca Kayıt Yeri erişimi izni almam gerekiyormuş. Herkese teşekkürler.

unit Unit2;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes,
System.Variants, System.IOUtils,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
FMX.Controls.Presentation,

System.Permissions,
System.Messaging,
{$IFDEF ANDROID}
Androidapi.JNI.Net,
Androidapi.JNI.GraphicsContentViewText,
Androidapi.JNI.JavaTypes,
Androidapi.Helpers,
Androidapi.JNI.App,
FMX.Platform.Android,
Androidapi.JNIBridge,
{$ENDIF}
FMX.StdActns,
FMX.MediaLibrary.Actions, FMX.Media, MobilePermissions.Model.Signature,
MobilePermissions.Model.Dangerous, MobilePermissions.Model.Standard,
MobilePermissions.Component;

type
TForm2 = class(TForm)
  Label1: TLabel;
  Button1: TButton;
  MediaPlayerControl1: TMediaPlayerControl;
  MediaPlayer1: TMediaPlayer;
  Timer1: TTimer;
  MobilePermissions1: TMobilePermissions;
  procedure Button1Click(Sender: TObject);
  procedure Timer1Timer(Sender: TObject);
  procedure FormShow(Sender: TObject);
private
  { Private declarations }
public
  { Public declarations }

{$IFDEF ANDROID}
  procedure HandleActivityMessage(const Sender: TObject; const M: TMessage);
  function HandleIntentAction(const Data: JIntent): Boolean;
{$ENDIF}
end;

var
Form2: TForm2;
fVideoFilename: string;
FMessageSubscriptionID: integer;

implementation

{$R *.fmx}

procedure TForm2.Button1Click(Sender: TObject);
var
{$IFDEF ANDROID}
chooserIntent, Intent: JIntent;
{$ENDIF}
ResultInt: integer;
begin
{$IFDEF ANDROID}
FMessageSubscriptionID := TMessageManager.DefaultManager.SubscribeToMessage
  (TMessageResultNotification, HandleActivityMessage);

intent := TJIntent.Create;
intent.setAction(TJIntent.JavaClass.ACTION_PICK);
intent.setType(StringToJString('video/*'));
chooserIntent := TJIntent.JavaClass.createChooser(intent,
  StrToJCharSequence('Choose media file'));
TAndroidHelper.Activity.startActivityForResult(chooserIntent,
  FMessageSubscriptionID);
{$ENDIF}
end;

{$IFDEF ANDROID}

procedure TForm2.FormShow(Sender: TObject);
begin
MobilePermissions1.Dangerous.ReadExternalStorage := True;
MobilePermissions1.Dangerous.WriteExternalStorage := True;
MobilePermissions1.Apply;
end;

procedure TForm2.HandleActivityMessage(const Sender: TObject;
const M: TMessage);
begin
if M is TMessageResultNotification then
  if HandleIntentAction(TMessageReceivedNotification(M).Value) then
  begin
    // A valid filename has been returned
    // Do The Videofile processing
  end;
Label1.text := fVideoFilename;
Timer1.Enabled := True;
end;

function TForm2.HandleIntentAction(const Data: JIntent): Boolean;
var
P: TJavaObjectArray<Jstring>;
// in case you want only specific fields... not used here. I have passed nil to get all the columns.
C: JCursor;
I: integer;
begin
P := nil;
// The following makes no difference
// P:=TJavaObjectArray<Jstring>.create(1);
// P.Items[0]:=StringToJstring('_data');

// this is suppose to give the information back to C ( : JCursor)
C := TAndroidHelper.Activity.getContentResolver.query(Data.getData, nil,
  // when projection is nil... it returns all columns. Ideally, you should only ask for the columns you need
  StringToJString(''),
  // java accepts nil... but you cannot give nil here, you need to give an empty JString
  nil, StringToJString(''));
// java accepts nil... but you cannot give nil here, you need to give an empty JString

C.moveToFirst;
Result := false;
for I := 0 to C.getColumnCount - 1 do
begin
  if JStringToString(C.getColumnName(I)) = '_data' then
  // '_data' column contains the path... you can use this to create the filestream to upload or do whatever....
  begin
    // fVideoFilename is a field of the form
    fVideoFilename := JStringToString(C.getString(I));
    Result := True;
    Break;
  end;
end;
if not Result then
  fVideoFilename := 'video file boş';
// P.Free;
end;
{$ENDIF}

procedure TForm2.Timer1Timer(Sender: TObject);
var
Path, FLibraryPath: string;
begin
Timer1.Enabled := false;
if FileExists(fVideoFilename) then
begin
  MediaPlayer1.FileName := fVideoFilename;
  MediaPlayer1.Play;
end
else
begin
  showmessage('Dosya bulunamadı: ' + fVideoFilename);
end;

end;

end.
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Alcinoe's play video xorpas 4 336 26-03-2024, Saat: 00:32
Son Yorum: gbg
  Android’de Dosya Depolama ve Paylaşma-2: And 11 SDK 30 Scoped Storage SAF MediaStore emozgun 12 4.916 19-03-2024, Saat: 22:29
Son Yorum: nguzeller
  IOS galeriden resim veya video seçme hakkında Mr.X 6 1.156 11-05-2023, Saat: 06:54
Son Yorum: emozgun
  Android *.gif Dosya Oynatma. hayalyilmaz43 15 3.571 05-05-2023, Saat: 10:11
Son Yorum: RAD Coder
  Mobil App. ile MQTT brokera bağlanma ve Veri çekme yemre 3 882 27-04-2023, Saat: 13:56
Son Yorum: yemre



Konuyu Okuyanlar: 1 Ziyaretçi